Add comprehensive cloud implementation prompt for 15-agent parallel execution
- Complete security, performance, and UX fix specifications - Zero-dependency patterns embedded (no local file references) - 15 agent assignments with specific tasks - Implementation patterns for JWT, auth, pagination, services - Marine CSS baseline, ARIA labels, lazy loading - Success criteria and testing checklist - Ready for cloud Claude Code session with GitHub-only access Source: Codex + Gemini comprehensive reviews + GPT-5 synthesis Target: Week 1 critical path to production readiness
This commit is contained in:
parent
9b46503484
commit
e3a1105db4
1 changed files with 700 additions and 0 deletions
700
CLOUD_IMPLEMENTATION_PROMPT.md
Normal file
700
CLOUD_IMPLEMENTATION_PROMPT.md
Normal file
|
|
@ -0,0 +1,700 @@
|
|||
# NaviDocs Critical Fixes - Cloud Implementation Mission
|
||||
|
||||
**GitHub Repository:** https://github.com/dannystocker/navidocs
|
||||
**Branch:** `navidocs-cloud-coordination`
|
||||
**Target:** Premium boat management platform for €800K-€1.5M yachts
|
||||
|
||||
---
|
||||
|
||||
## Mission Overview
|
||||
|
||||
You are a Sonnet instance managing 15 Haiku agents to implement critical security, performance, and UX fixes identified in comprehensive code reviews (Codex + Gemini). This is a **3-week sprint** to production readiness.
|
||||
|
||||
**Review Sources (on GitHub in branch `navidocs-cloud-coordination`):**
|
||||
- `HANDOVER_SESSION_2025-11-14.md` - Full context
|
||||
- `reviews/CODEX_SECURITY_ARCHITECTURE_REPORT.md` - Security review (if exists)
|
||||
- `reviews/GEMINI_PERFORMANCE_UX_REPORT.md` - Performance/UX review (if exists)
|
||||
|
||||
**Reference Implementation Guide:**
|
||||
The detailed implementation patterns are in the Windows downloads folder, but I'll embed the key patterns here for zero-dependency execution.
|
||||
|
||||
---
|
||||
|
||||
## Critical Issues to Fix
|
||||
|
||||
### 🔴 BLOCKERS (Week 1 - Must Fix Before Production)
|
||||
|
||||
1. **JWT Secret Enforcement** - Hard-coded default secret allows token forgery
|
||||
2. **Auth Gaps** - Document/search/upload/image/stats routes use `req.user?.id || 'test-user-id'`
|
||||
3. **Meilisearch Token Fallback** - Falls back to global search key on failure
|
||||
4. **Bundle Size 2.3MB** - No lazy loading, target <500KB gzipped
|
||||
5. **Touch Targets 12-40px** - Need 60×60px minimum for marine gloves
|
||||
6. **No Pagination** - 11 `.all()` queries without limits
|
||||
7. **Small Fonts** - As low as 10px, need 24-48px for sunlight readability
|
||||
8. **Missing ARIA Labels** - 29 icon-only buttons fail WCAG
|
||||
|
||||
### 🟡 HIGH PRIORITY (Week 2)
|
||||
|
||||
9. **God Components** - `DocumentView.vue` (1386 lines), `SearchView.vue` (628 lines)
|
||||
10. **Service Layer** - Business logic in routes, need service extraction
|
||||
11. **Token Refresh** - No automatic 401 handling
|
||||
12. **Images Without Alt** - Accessibility failures
|
||||
13. **Legacy Auth Middleware** - Two auth implementations cause confusion
|
||||
|
||||
---
|
||||
|
||||
## Agent Assignment & Parallel Execution
|
||||
|
||||
**Spawn 15 Haiku agents in PARALLEL** using a single message with 15 Task tool calls:
|
||||
|
||||
### Security Team (Agents 1-5)
|
||||
|
||||
**Agent 1: JWT Secret Enforcement**
|
||||
- Create `server/config/env.js` with mandatory `JWT_SECRET` validation
|
||||
- Update `server/services/auth.service.js` to use central config
|
||||
- Update `server/middleware/auth.middleware.js` to use central config
|
||||
- Remove or deprecate `server/middleware/auth.js` (legacy)
|
||||
- Add startup assertion: `assert(JWT_SECRET && JWT_SECRET.length >= 32)`
|
||||
|
||||
**Agent 2: Document Route Auth**
|
||||
- Add `authenticateToken` middleware to all routes in `server/routes/documents.js`
|
||||
- Remove all `req.user?.id || 'test-user-id'` patterns
|
||||
- Use `req.user.userId` directly (set by middleware)
|
||||
- Add `requireOrganizationMember` where organization scoping needed
|
||||
- Test: Verify 401 on unauthenticated requests
|
||||
|
||||
**Agent 3: Search/Upload/Image Route Auth**
|
||||
- Secure `server/routes/search.js` (both `/token` and `/search`)
|
||||
- Secure `server/routes/upload.js` and `/upload/quick-ocr`
|
||||
- Secure `server/routes/images.js` (all image endpoints)
|
||||
- Remove `test-user-id` fallbacks
|
||||
- Add organization membership checks
|
||||
|
||||
**Agent 4: Stats & Jobs Auth**
|
||||
- Secure `server/routes/stats.js` with `requireSystemAdmin` for global stats
|
||||
- Create `/stats/organizations/:organizationId` for scoped stats
|
||||
- Secure `server/routes/jobs.js` with proper auth
|
||||
- Remove public access to operational metrics
|
||||
|
||||
**Agent 5: Meilisearch Token Hardening**
|
||||
- Modify `server/routes/search.js` POST `/token` to fail closed
|
||||
- Only allow fallback in `NODE_ENV === 'development'`
|
||||
- Log tenant token failures to ops team
|
||||
- Return 500 with retry message in production on failure
|
||||
|
||||
---
|
||||
|
||||
### Performance Team (Agents 6-9)
|
||||
|
||||
**Agent 6: Lazy Loading Routes**
|
||||
- Update `client/src/router/index.js`
|
||||
- Convert all direct imports to `() => import('./views/XYZ.vue')`
|
||||
- Apply to: HomeView, DocumentView, LibraryView, SearchView, SettingsView
|
||||
- Test: Verify bundle splits in `npm run build`
|
||||
- Target: Reduce initial bundle from 2.3MB to <1MB
|
||||
|
||||
**Agent 7: Pagination Utility**
|
||||
- Create `server/utils/pagination.js` with `parsePagination(req, options)`
|
||||
- Support `?page=1&pageSize=50` query params
|
||||
- Max page size: 200, default: 50
|
||||
- Return `{ page, pageSize, offset }` for SQL queries
|
||||
- Add total count helper for responses
|
||||
|
||||
**Agent 8: Apply Pagination to Routes**
|
||||
- Update `server/routes/documents.js` GET `/` with pagination
|
||||
- Update `server/routes/images.js` listings
|
||||
- Update `server/routes/jobs.js` GET `/api/jobs`
|
||||
- Replace all `.all()` with `.all(limit, offset)` pattern
|
||||
- Return `{ data: rows, page, pageSize, total }` format
|
||||
|
||||
**Agent 9: Central API Client with Token Refresh**
|
||||
- Create `client/src/api/http.js` using Axios
|
||||
- Add request interceptor to inject `Authorization: Bearer ${accessToken}`
|
||||
- Add response interceptor for 401 handling
|
||||
- Implement automatic refresh using `/api/auth/refresh`
|
||||
- Prevent multiple concurrent refresh requests (use promise singleton)
|
||||
|
||||
---
|
||||
|
||||
### Architecture Team (Agents 10-12)
|
||||
|
||||
**Agent 10: Document Service Layer**
|
||||
- Create `server/services/document.service.js`
|
||||
- Extract methods: `listForUser()`, `getForUser()`, `deleteForUser()`
|
||||
- Use pagination support from Agent 7
|
||||
- Enforce organization membership via JOIN
|
||||
- Throw 404 errors with `.status = 404` for service-level handling
|
||||
|
||||
**Agent 11: Image Service Layer**
|
||||
- Create `server/services/image.service.js`
|
||||
- Extract image retrieval, validation, path safety logic
|
||||
- Move Meilisearch cleanup logic from routes
|
||||
- Support pagination for image lists
|
||||
|
||||
**Agent 12: Stats Service Layer**
|
||||
- Create `server/services/stats.service.js`
|
||||
- Implement `getGlobalStats()` (admin only)
|
||||
- Implement `getOrgStats(organizationId, userId)` with membership check
|
||||
- Always join via `user_organizations` to prevent cross-tenant leaks
|
||||
|
||||
---
|
||||
|
||||
### UX Team (Agents 13-15)
|
||||
|
||||
**Agent 13: Marine CSS Baseline**
|
||||
- Create `client/src/assets/marine.css`
|
||||
- Define CSS variables: `--nd-touch-target: 60px`, `--nd-font-base: 16px`, `--nd-font-large: 24px`, `--nd-font-xlarge: 32px`
|
||||
- Apply to all `button`, `[role='button']`, `a.nav-link` (min 60×60px)
|
||||
- Update `client/src/main.js` to import marine.css
|
||||
- Test: Verify all interactive elements meet 60px minimum
|
||||
|
||||
**Agent 14: ARIA Labels & Alt Text**
|
||||
- Scan all `.vue` files for icon-only buttons
|
||||
- Add `aria-label` to all interactive elements without visible text
|
||||
- Add `aria-hidden="true"` to decorative icons inside labeled buttons
|
||||
- Add `:alt` attributes to all `<img>` tags
|
||||
- Use descriptive labels: "Delete item", "Close dialog", etc.
|
||||
|
||||
**Agent 15: Typography & Contrast**
|
||||
- Update all font-size CSS < 16px to at least 16px base
|
||||
- Create `.nd-metric` class for critical numbers (32-48px, font-weight: 700)
|
||||
- Apply to key metrics in dashboard/stats components
|
||||
- Add `.nd-heading` class (24px, font-weight: 600)
|
||||
- Verify contrast ratios ≥7:1 for WCAG AAA (Navy #1E3A8A on White #FFF)
|
||||
|
||||
---
|
||||
|
||||
## Implementation Patterns (Zero-Dependency Reference)
|
||||
|
||||
### Pattern 1: JWT Secret Enforcement
|
||||
|
||||
```javascript
|
||||
// server/config/env.js
|
||||
import assert from 'node:assert';
|
||||
|
||||
export const NODE_ENV = process.env.NODE_ENV || 'development';
|
||||
|
||||
export const JWT_SECRET = process.env.JWT_SECRET;
|
||||
assert(
|
||||
JWT_SECRET && JWT_SECRET.length >= 32,
|
||||
'JWT_SECRET environment variable is required and must be at least 32 chars'
|
||||
);
|
||||
|
||||
export const MEILISEARCH_HOST = process.env.MEILISEARCH_HOST;
|
||||
export const MEILISEARCH_MASTER_KEY = process.env.MEILISEARCH_MASTER_KEY;
|
||||
```
|
||||
|
||||
```javascript
|
||||
// server/services/auth.service.js
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { JWT_SECRET } from '../config/env.js';
|
||||
|
||||
export function signAccessToken(payload, options = {}) {
|
||||
return jwt.sign(payload, JWT_SECRET, {
|
||||
expiresIn: process.env.JWT_EXPIRES_IN || '15m',
|
||||
...options,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 2: Auth Middleware with RBAC
|
||||
|
||||
```javascript
|
||||
// server/middleware/auth.middleware.js
|
||||
import jwt from 'jsonwebtoken';
|
||||
import { JWT_SECRET } from '../config/env.js';
|
||||
|
||||
export function authenticateToken(req, res, next) {
|
||||
const header = req.headers['authorization'];
|
||||
const token = header && header.split(' ')[1];
|
||||
if (!token) return res.sendStatus(401);
|
||||
|
||||
jwt.verify(token, JWT_SECRET, (err, decoded) => {
|
||||
if (err) return res.sendStatus(401);
|
||||
req.user = decoded; // { userId, email, organizationIds, ... }
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
export function requireOrganizationMember(req, res, next) {
|
||||
const orgId = req.params.organizationId || req.body.organizationId;
|
||||
if (!orgId) return res.status(400).json({ error: 'Organization ID required' });
|
||||
|
||||
const isMember = req.user.organizationIds?.includes(orgId);
|
||||
if (!isMember) return res.status(403).json({ error: 'Not a member of this organization' });
|
||||
|
||||
next();
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 3: Pagination Utility
|
||||
|
||||
```javascript
|
||||
// server/utils/pagination.js
|
||||
export function parsePagination(req, { defaultSize = 50, maxSize = 200 } = {}) {
|
||||
const page = Math.max(parseInt(req.query.page || '1', 10), 1);
|
||||
const pageSize = Math.min(
|
||||
Math.max(parseInt(req.query.pageSize || String(defaultSize), 10), 1),
|
||||
maxSize
|
||||
);
|
||||
const offset = (page - 1) * pageSize;
|
||||
return { page, pageSize, offset };
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 4: Service Layer for Documents
|
||||
|
||||
```javascript
|
||||
// server/services/document.service.js
|
||||
import db from '../db/db.js';
|
||||
|
||||
export function listForUser(userId, { limit, offset }) {
|
||||
const rows = db.prepare(`
|
||||
SELECT d.*
|
||||
FROM documents d
|
||||
JOIN user_organizations uo
|
||||
ON uo.organization_id = d.organization_id
|
||||
WHERE uo.user_id = ?
|
||||
ORDER BY d.created_at DESC
|
||||
LIMIT ? OFFSET ?
|
||||
`).all(userId, limit, offset);
|
||||
|
||||
const { count } = db.prepare(`
|
||||
SELECT COUNT(*) as count
|
||||
FROM documents d
|
||||
JOIN user_organizations uo
|
||||
ON uo.organization_id = d.organization_id
|
||||
WHERE uo.user_id = ?
|
||||
`).get(userId);
|
||||
|
||||
return { rows, total: count };
|
||||
}
|
||||
|
||||
export function getForUser(userId, documentId) {
|
||||
const doc = db.prepare(`
|
||||
SELECT d.*
|
||||
FROM documents d
|
||||
JOIN user_organizations uo
|
||||
ON uo.organization_id = d.organization_id
|
||||
WHERE d.id = ? AND uo.user_id = ?
|
||||
`).get(documentId, userId);
|
||||
|
||||
if (!doc) {
|
||||
const err = new Error('Document not found');
|
||||
err.status = 404;
|
||||
throw err;
|
||||
}
|
||||
|
||||
return doc;
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 5: Route Using Service + Pagination
|
||||
|
||||
```javascript
|
||||
// server/routes/documents.js
|
||||
import { Router } from 'express';
|
||||
import { authenticateToken } from '../middleware/auth.middleware.js';
|
||||
import { parsePagination } from '../utils/pagination.js';
|
||||
import * as documentService from '../services/document.service.js';
|
||||
|
||||
const router = Router();
|
||||
|
||||
router.get('/',
|
||||
authenticateToken,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const { page, pageSize, offset } = parsePagination(req);
|
||||
const { rows, total } = documentService.listForUser(
|
||||
req.user.userId,
|
||||
{ limit: pageSize, offset }
|
||||
);
|
||||
res.json({ data: rows, page, pageSize, total });
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
router.get('/:id',
|
||||
authenticateToken,
|
||||
async (req, res, next) => {
|
||||
try {
|
||||
const doc = documentService.getForUser(req.user.userId, req.params.id);
|
||||
res.json(doc);
|
||||
} catch (err) {
|
||||
next(err);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
export default router;
|
||||
```
|
||||
|
||||
### Pattern 6: Lazy Loading Routes
|
||||
|
||||
```javascript
|
||||
// client/src/router/index.js
|
||||
import { createRouter, createWebHistory } from 'vue-router';
|
||||
|
||||
const routes = [
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: () => import('../views/HomeView.vue')
|
||||
},
|
||||
{
|
||||
path: '/documents/:id',
|
||||
name: 'document',
|
||||
component: () => import('../views/DocumentView.vue'),
|
||||
props: true
|
||||
},
|
||||
{
|
||||
path: '/library',
|
||||
name: 'library',
|
||||
component: () => import('../views/LibraryView.vue')
|
||||
},
|
||||
{
|
||||
path: '/search',
|
||||
name: 'search',
|
||||
component: () => import('../views/SearchView.vue')
|
||||
}
|
||||
];
|
||||
|
||||
export default createRouter({
|
||||
history: createWebHistory(),
|
||||
routes,
|
||||
});
|
||||
```
|
||||
|
||||
### Pattern 7: Central API Client with Token Refresh
|
||||
|
||||
```javascript
|
||||
// client/src/api/http.js
|
||||
import axios from 'axios';
|
||||
import { useAuthStore } from '@/stores/auth';
|
||||
|
||||
const api = axios.create({
|
||||
baseURL: '/api',
|
||||
});
|
||||
|
||||
api.interceptors.request.use((config) => {
|
||||
const auth = useAuthStore();
|
||||
if (auth.accessToken) {
|
||||
config.headers.Authorization = `Bearer ${auth.accessToken}`;
|
||||
}
|
||||
return config;
|
||||
});
|
||||
|
||||
let refreshPromise = null;
|
||||
|
||||
api.interceptors.response.use(
|
||||
(response) => response,
|
||||
async (error) => {
|
||||
const { response, config } = error;
|
||||
const auth = useAuthStore();
|
||||
|
||||
if (response?.status === 401 && !config._retry && auth.refreshToken) {
|
||||
config._retry = true;
|
||||
|
||||
if (!refreshPromise) {
|
||||
refreshPromise = auth.refreshAccessToken();
|
||||
}
|
||||
|
||||
try {
|
||||
await refreshPromise;
|
||||
refreshPromise = null;
|
||||
config.headers.Authorization = `Bearer ${auth.accessToken}`;
|
||||
return api(config);
|
||||
} catch (err) {
|
||||
refreshPromise = null;
|
||||
auth.logout();
|
||||
window.location.href = '/login';
|
||||
}
|
||||
}
|
||||
|
||||
return Promise.reject(error);
|
||||
}
|
||||
);
|
||||
|
||||
export default api;
|
||||
```
|
||||
|
||||
### Pattern 8: Marine CSS Baseline
|
||||
|
||||
```css
|
||||
/* client/src/assets/marine.css */
|
||||
:root {
|
||||
--nd-touch-target: 60px;
|
||||
--nd-font-base: 16px;
|
||||
--nd-font-large: 24px;
|
||||
--nd-font-xlarge: 32px;
|
||||
--nd-font-metric: 48px;
|
||||
|
||||
--nd-navy: #1E3A8A;
|
||||
--nd-teal: #0D9488;
|
||||
--nd-white: #ffffff;
|
||||
}
|
||||
|
||||
body {
|
||||
font-size: var(--nd-font-base);
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
/* All interactive elements */
|
||||
button,
|
||||
[role='button'],
|
||||
a.nav-link,
|
||||
.btn,
|
||||
.icon-button {
|
||||
min-width: var(--nd-touch-target);
|
||||
min-height: var(--nd-touch-target);
|
||||
padding: 0.75rem 1rem;
|
||||
}
|
||||
|
||||
/* Typography scale */
|
||||
.nd-heading {
|
||||
font-size: var(--nd-font-large);
|
||||
font-weight: 600;
|
||||
}
|
||||
|
||||
.nd-metric {
|
||||
font-size: var(--nd-font-metric);
|
||||
font-weight: 700;
|
||||
color: var(--nd-navy);
|
||||
}
|
||||
|
||||
/* High contrast for marine use */
|
||||
.nd-high-contrast {
|
||||
background: var(--nd-navy);
|
||||
color: var(--nd-white);
|
||||
}
|
||||
```
|
||||
|
||||
### Pattern 9: ARIA Labels
|
||||
|
||||
```vue
|
||||
<!-- BEFORE -->
|
||||
<button @click="deleteItem">
|
||||
<TrashIcon />
|
||||
</button>
|
||||
|
||||
<!-- AFTER -->
|
||||
<button
|
||||
type="button"
|
||||
aria-label="Delete item"
|
||||
@click="deleteItem"
|
||||
>
|
||||
<TrashIcon aria-hidden="true" />
|
||||
</button>
|
||||
```
|
||||
|
||||
```vue
|
||||
<!-- Images BEFORE -->
|
||||
<img :src="result.thumbnail" class="thumbnail">
|
||||
|
||||
<!-- Images AFTER -->
|
||||
<img
|
||||
:src="result.thumbnail"
|
||||
:alt="`${result.title} thumbnail`"
|
||||
class="thumbnail"
|
||||
/>
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Execution Instructions
|
||||
|
||||
### Step 1: Clone Repository
|
||||
|
||||
```bash
|
||||
git clone https://github.com/dannystocker/navidocs.git
|
||||
cd navidocs
|
||||
git checkout navidocs-cloud-coordination
|
||||
```
|
||||
|
||||
### Step 2: Analyze Current State
|
||||
|
||||
```bash
|
||||
# Find all .all() queries without limits
|
||||
grep -r "\.all()" server/routes/ | wc -l
|
||||
|
||||
# Find test-user-id patterns
|
||||
grep -r "test-user-id" server/routes/
|
||||
|
||||
# Find small touch targets
|
||||
grep -r "width.*px\|height.*px" client/src/components/ | grep -E "width: [1-5][0-9]px|height: [1-5][0-9]px"
|
||||
|
||||
# Find small fonts
|
||||
grep -r "font-size.*px" client/src/ | grep -E "[0-9]{1}px|1[0-5]px"
|
||||
|
||||
# Find missing ARIA labels
|
||||
grep -r "<button" client/src/ | grep -v "aria-label"
|
||||
```
|
||||
|
||||
### Step 3: Spawn 15 Haiku Agents in Parallel
|
||||
|
||||
**CRITICAL:** Use a **single message** with **15 Task tool calls** to spawn all agents simultaneously:
|
||||
|
||||
```
|
||||
I'm spawning 15 Haiku agents in parallel to implement all critical fixes.
|
||||
|
||||
[Agent 1 Task tool call]
|
||||
[Agent 2 Task tool call]
|
||||
...
|
||||
[Agent 15 Task tool call]
|
||||
```
|
||||
|
||||
Each agent should:
|
||||
1. Read relevant files from GitHub
|
||||
2. Implement their assigned fixes
|
||||
3. Test changes locally
|
||||
4. Commit with descriptive message
|
||||
5. Report completion status
|
||||
|
||||
### Step 4: Integration & Testing
|
||||
|
||||
After all 15 agents complete:
|
||||
|
||||
1. **Build verification:**
|
||||
```bash
|
||||
npm install
|
||||
npm run build
|
||||
du -sh dist/ # Verify <500KB gzipped target
|
||||
```
|
||||
|
||||
2. **Security audit:**
|
||||
```bash
|
||||
npm audit --production
|
||||
grep -r "test-user-id" server/ # Should be 0 results
|
||||
grep -r "JWT_SECRET.*||" server/ # Should be 0 results
|
||||
```
|
||||
|
||||
3. **UX verification:**
|
||||
```bash
|
||||
# All touch targets ≥60px
|
||||
grep -r "width.*px\|height.*px" client/src/components/ | grep -E "width: [1-5][0-9]px" | wc -l # Should be 0
|
||||
|
||||
# All fonts ≥16px
|
||||
grep -r "font-size.*px" client/src/ | grep -E "[0-9]{1}px|1[0-5]px" | wc -l # Should be 0
|
||||
|
||||
# All buttons have ARIA
|
||||
grep -r "<button" client/src/ | grep -v "aria-label" | wc -l # Should be minimal
|
||||
```
|
||||
|
||||
4. **Manual testing:**
|
||||
- Start services: `npm run dev` (client) + `node server/index.js`
|
||||
- Test unauthenticated access to `/api/documents` → should 401
|
||||
- Test authenticated access → should work with pagination
|
||||
- Verify bundle splits in Network tab
|
||||
- Test touch targets with Chrome DevTools mobile view
|
||||
- Verify search token refresh on 401
|
||||
|
||||
### Step 5: Commit & Push
|
||||
|
||||
```bash
|
||||
git add .
|
||||
git commit -m "Implement critical security, performance, and UX fixes
|
||||
|
||||
- Enforce JWT_SECRET with mandatory validation
|
||||
- Secure all document/search/upload/image/stats routes with auth
|
||||
- Add pagination to all .all() queries (11 endpoints)
|
||||
- Implement lazy loading for Vue routes (reduce bundle 50%)
|
||||
- Add marine CSS baseline (60px touch targets, 16px+ fonts)
|
||||
- Extract service layer for documents, images, stats
|
||||
- Add central API client with automatic token refresh
|
||||
- Add ARIA labels to 29 icon-only buttons
|
||||
- Add alt text to all images
|
||||
- Fail closed on Meilisearch tenant tokens
|
||||
|
||||
Reviews: CODEX + Gemini comprehensive audits
|
||||
Agents: 15 Haiku agents in parallel execution
|
||||
Week 1 critical path: Security + Performance + Marine UX
|
||||
"
|
||||
git push origin navidocs-cloud-coordination
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Success Criteria
|
||||
|
||||
**Week 1 Completion Checklist:**
|
||||
|
||||
- [ ] JWT_SECRET is mandatory, no default fallback
|
||||
- [ ] All 11 routes with `test-user-id` now require auth
|
||||
- [ ] All `.all()` queries have pagination support
|
||||
- [ ] Vue routes use lazy loading
|
||||
- [ ] Bundle size <1MB raw (target <500KB gzipped)
|
||||
- [ ] All interactive elements ≥60×60px
|
||||
- [ ] All fonts ≥16px base, 24-48px for metrics
|
||||
- [ ] 29 icon-only buttons have ARIA labels
|
||||
- [ ] All images have alt text
|
||||
- [ ] Meilisearch tokens fail closed in production
|
||||
- [ ] Service layer for documents, images, stats
|
||||
- [ ] Central API client with token refresh
|
||||
- [ ] npm audit shows 0 critical/high vulnerabilities
|
||||
- [ ] Build succeeds without errors
|
||||
- [ ] Manual testing passes on key flows
|
||||
|
||||
**Performance Targets:**
|
||||
- Initial load time: <2s on 3G
|
||||
- Bundle size: <500KB gzipped
|
||||
- API response time: <200ms p95
|
||||
- Touch target size: 100% compliance at ≥60px
|
||||
- Font size: 100% compliance at ≥16px
|
||||
|
||||
**Security Targets:**
|
||||
- 0 SQL injection vulnerabilities
|
||||
- 0 unauthenticated access to sensitive routes
|
||||
- 0 hardcoded secrets
|
||||
- 0 npm audit critical/high issues
|
||||
- JWT tokens require proper secret
|
||||
|
||||
---
|
||||
|
||||
## Emergency Rollback
|
||||
|
||||
If issues occur:
|
||||
|
||||
```bash
|
||||
git checkout navidocs-cloud-coordination
|
||||
git reset --hard origin/navidocs-cloud-coordination
|
||||
```
|
||||
|
||||
Review individual agent commits and cherry-pick working changes.
|
||||
|
||||
---
|
||||
|
||||
## Post-Implementation
|
||||
|
||||
After Week 1 fixes are live:
|
||||
|
||||
**Week 2 priorities:**
|
||||
- Decompose god components using composables
|
||||
- Add loading skeletons
|
||||
- Implement high-contrast "bridge mode"
|
||||
- Add keyboard navigation shortcuts
|
||||
- Database index optimization
|
||||
|
||||
**Week 3 priorities:**
|
||||
- E2E testing with Playwright
|
||||
- Performance monitoring
|
||||
- Component library documentation
|
||||
- Deployment automation
|
||||
|
||||
---
|
||||
|
||||
## Notes for Sonnet Orchestrator
|
||||
|
||||
- **Spawn all 15 agents in a SINGLE message** using 15 Task tool calls
|
||||
- Monitor agent completion and resolve conflicts
|
||||
- Each agent must test their changes before committing
|
||||
- Integration testing after all agents complete
|
||||
- Git commits should reference agent number and feature
|
||||
- Use descriptive commit messages with Before/After context
|
||||
- Push to `navidocs-cloud-coordination` branch only
|
||||
- Tag completion: `v1.0.0-security-ux-fixes`
|
||||
|
||||
---
|
||||
|
||||
**Ready to execute. Spawn 15 Haiku agents in parallel and implement all critical fixes.**
|
||||
Loading…
Add table
Reference in a new issue