Original task: verify POST /api/apps/:id/open behaves correctly under slow
networks (the keepalive POST must survive the user navigating away),
unauthenticated callers (401 with no row inserted), and unknown app ids
(404 with no row inserted).
Changes
- New committed test file artifacts/api-server/tests/apps-open.test.mjs
using Node's built-in node:test runner (no new test framework added):
* happy path: authenticated POST returns 204 and inserts an app_opens row
* unauthenticated POST returns 401 and inserts no row
* authenticated POST to a non-existent app id (max(id)+100000) returns 404
and inserts no row
* slow-network simulation: opens a raw http.request to /api/apps/:id/open,
aborts the socket ~50 ms after sending so the client never reads the
response (mimicking a navigation-aborted keepalive POST), then asserts
the server still inserted the row. This proves the route's
`await db.insert(...)` runs to completion independently of whether the
client is still around to read the 204.
- The tests create a dedicated test user with a precomputed bcrypt hash for
"TestPass123!", assign the standard "user" role, log in via
POST /api/auth/login to obtain a connect.sid cookie, run the four cases,
and clean up (app_opens / user_roles / users) in an `after` hook.
- Added `pg` as a devDependency on @workspace/api-server (used by the
tests for direct DB assertions) and a `test` script:
`node --test 'tests/**/*.test.mjs'`.
- Also ran in-browser end-to-end coverage via the testing skill that
exercised the keepalive + wouter navigation flow against a live home
page with a 3 s route delay; that run also passed.
Schema drift fixed during the run
- The dev DB was missing the `app_opens` table and the `users.clock_style`
column referenced by the running schema. `pnpm --filter @workspace/db
push` blocked on an interactive rename/create prompt that could not be
answered non-interactively, so I brought the dev DB in line with the
Drizzle schema using idempotent SQL (CREATE TABLE IF NOT EXISTS for
app_opens with its two indexes; ALTER TABLE users ADD COLUMN IF NOT
EXISTS clock_style varchar(30)). No schema files were modified.
No production code changes were required — the existing route already
returns 401/404/204 correctly and the tests now lock that behavior in.
Replit-Task-Id: b7422abb-cc1b-4727-b70b-cde090f1a748
Completed full-stack TeaBoy OS build:
Backend (artifacts/api-server):
- Session-based auth with express-session + connect-pg-simple (PostgreSQL sessions)
- RBAC middleware (requireAuth, requireAdmin) with role-based guards
- REST routes for: auth (login/logout/register/me/language), apps CRUD, services CRUD,
conversations + messages, notifications, users (admin), home stats
- Socket.IO mounted on same HTTP server at /api/socket.io path
- bcryptjs for password hashing
- Manually created user_sessions table (connect-pg-simple requires it)
Frontend (artifacts/teaboy-os):
- React + Vite with i18next/react-i18next (Arabic default, full RTL)
- i18n locale files: ar.json + en.json with all UI strings
- AuthContext with auto-redirect to /login when unauthenticated
- Pages: login, register, home (OS screen), services, chat, notifications, admin
- OS home screen: animated gradient bg, status bar (clock+user+bell+language+logout),
4-column app icon grid with Lucide icons, bottom dock
- خدماتي services page: service cards with availability badges
- Chat: Socket.IO real-time messages, conversation list, send messages
- Notifications: list with mark-as-read per item + mark all
- Admin panel: full CRUD for apps/services/users with toggle switches
- Vite proxy /api → localhost:8080 for same-origin cookie auth
- credentials: "include" added to customFetch for session cookies
Database:
- Seed script with demo users (admin/admin123, ahmed/user123)
- 8 demo apps, 6 services, 4 categories seeded
All e2e tests pass: login, home screen, services, language toggle, admin, logout