99 lines
5.2 KiB
Markdown
99 lines
5.2 KiB
Markdown
# Audit, testing, and cleanup — results
|
||
|
||
Generated as part of the three-phase plan. The plan file itself was not edited.
|
||
|
||
---
|
||
|
||
## Phase 1 — Functional testing (automated)
|
||
|
||
**Environment:** `GET http://127.0.0.1:3030/...` without `Authorization: Bearer` unless noted.
|
||
|
||
| Area | Endpoint / check | Result | Notes |
|
||
|------|------------------|--------|--------|
|
||
| Health | `GET /api/health` | **Works** | 200, JSON `service: mailflow-api` |
|
||
| Auth | `GET /api/me` | **401** | Expected without JWT |
|
||
| Email | `GET /api/email/accounts` | **401** | Protected |
|
||
| Email | `GET /api/email/stats` | **401** | Protected |
|
||
| Email | `GET /api/email/categories` | **401** | Protected |
|
||
| Email | `POST /api/email/sort` (body `{"accountId":"test"}` via `--data-binary @file`) | **401** | JSON parses; fails at **auth**, not body-parser |
|
||
| Onboarding | `GET /api/onboarding/status` | **401** | Protected |
|
||
| OAuth | `GET /api/oauth/status` | **Works** | 200, gmail/outlook config (no auth on this route) |
|
||
| Digest / subscription / referrals | (from earlier smoke) | **401** | Without token |
|
||
|
||
**Manual (browser) — not automated here**
|
||
|
||
| Area | Result |
|
||
|------|--------|
|
||
| Login / logout, JWT expiry, `ProtectedRoute` | **Not run** — requires Appwrite session in browser |
|
||
| Dashboard loads, stats, digest, subscription, referral UI | **Not run** |
|
||
| `POST /api/email/connect`, Gmail/Outlook/IMAP | **Not run** |
|
||
| `GET /api/oauth/gmail/connect` redirect | **Not run** |
|
||
| Admin bypass `support@webklar.com` | **Not run** |
|
||
| Mistral key validity | **Not run** — needs sort path that calls AI |
|
||
|
||
**Sort failure diagnosis (without JWT)**
|
||
|
||
- Valid JSON + no Bearer → **401** at `requireAuthUnlessEmailWebhook` — **before** subscription, account fetch, or sorting.
|
||
|
||
**Recommended next step:** With a real JWT, call `POST /api/email/sort` with a **demo** `accountId` first, then inspect server logs for the first error after auth.
|
||
|
||
---
|
||
|
||
## Phase 2 — Code audit (summary)
|
||
|
||
**Legend:** A=dead code, B=duplicate logic, C=performance, D=inconsistent errors, E=console/debug, F=TODO/FIXME, G=file >500 lines, H=hardcoded config
|
||
|
||
### Server (`server/`)
|
||
|
||
| File | Lines (approx) | A–H notes |
|
||
|------|----------------|-----------|
|
||
| [index.mjs](server/index.mjs) | ~415 | E: startup `console.log` (acceptable). |
|
||
| [routes/email.mjs](server/routes/email.mjs) | **~1700+** | **G** — primary candidate to split (handlers vs Gmail/IMAP/demo). **F** — one `TODO` (~line 1659). D: collection errors partly handled via `db` + route try/catch. |
|
||
| [routes/stripe.mjs](server/routes/stripe.mjs) | ~400 | D: admin + collection fallbacks present. |
|
||
| [routes/oauth.mjs](server/routes/oauth.mjs) | — | OAuth flows; review token refresh paths when testing. |
|
||
| [routes/api.mjs](server/routes/api.mjs) | ~400 | Referral handler null-checks `getOrCreateCode`. |
|
||
| [routes/analytics.mjs](server/routes/analytics.mjs) | — | E: `console.log` only when `NODE_ENV === 'development'`. |
|
||
| [routes/webhook.mjs](server/routes/webhook.mjs) | — | — |
|
||
| [services/database.mjs](server/services/database.mjs) | **~730** | **G.** B: `isCollectionNotFound` vs inline check in `list()` — aligned in Phase 3. D: `create`/`update` return `null` if collection missing — callers must tolerate. |
|
||
| [middleware/*](server/middleware/) | — | Centralized errors, auth, validate. |
|
||
| [config/index.mjs](server/config/index.mjs) | — | H: env-driven; admin emails include `support@webklar.com`. |
|
||
| [utils/*](server/utils/) | — | `appwriteErrors.mjs` for route-level collection detection. |
|
||
|
||
### Client (`client/src/`)
|
||
|
||
| File | Lines (approx) | A–H notes |
|
||
|------|----------------|-----------|
|
||
| [pages/Dashboard.tsx](client/src/pages/Dashboard.tsx) | **~970** | **G.** Auth-gated `loadData`. |
|
||
| [pages/Settings.tsx](client/src/pages/Settings.tsx) | **~2660+** | **G** — largest UI file; future split by section. |
|
||
| [lib/api.ts](client/src/lib/api.ts) | ~749 | Central API; `resolveApiBase` type guard for `raw`. |
|
||
| [lib/appwrite.ts](client/src/lib/appwrite.ts) | ~172 | JWT cache, session checks. |
|
||
| [context/AuthContext.tsx](client/src/context/AuthContext.tsx) | ~107 | Not under `contexts/` (path note from plan). |
|
||
| [lib/analytics.ts](client/src/lib/analytics.ts) | — | E: `console.log` in `DEV` for events. |
|
||
|
||
**TODO/FIXME grep (sample):** server `email.mjs` — 1 TODO; client — analytics dev log only.
|
||
|
||
---
|
||
|
||
## Phase 3 — Changes executed (after scope approval)
|
||
|
||
| File | Change | Risk | Verify |
|
||
|------|--------|------|--------|
|
||
| [server/services/database.mjs](server/services/database.mjs) | `list()` catch delegates to `isCollectionNotFound(err)` (DRY). `emailStats.increment` / `emailUsage.increment`: if `db.update`/`db.create` returns `null`, `log.warn` in **development** only (avoids silent failure when collections are missing). | Low | Restart server; `GET /api/health` 200; sort path unchanged except optional dev warnings. |
|
||
|
||
**Not done in this pass (defer):** splitting `email.mjs` / `Settings.tsx`, removing all dead imports project-wide (high churn).
|
||
|
||
---
|
||
|
||
## Files touched (Phase 3)
|
||
|
||
- `server/services/database.mjs`
|
||
- `AUDIT_RESULTS.md` (this file)
|
||
|
||
Temporary file `_sort-body.json` removed if present (curl helper).
|
||
|
||
---
|
||
|
||
## Restart
|
||
|
||
After changes: `cd server && node index.mjs` — confirm `GET /api/health` returns 200.
|