AI-Generated Test Suite
AI can quickly draft test cases, but a generated suite is only useful after you review its assertions and run it against the actual code. Give AI the implementation to test, then inspect failures and missing coverage.
Backend API Tests
Write a complete test suite for the Taskflow API using Vitest and supertest.
Here's the Express app: [paste index.ts]
Auth routes: [paste auth.ts]
Project routes: [paste projects.ts]
Task routes: [paste tasks.ts]
Test structure:
1. Auth tests: register (success + duplicate email + validation), login (success + wrong password + wrong email), token validation
2. Project tests: create (success + missing name), list (only own projects), archive, verify archived projects hidden from list
3. Task tests: create (success + validation), update, delete, move (status change + position calculation), verify completed_at set when moved to done
4. Authorization tests: verify all endpoints reject requests without token, verify users can't access other users' projects
Use a fresh in-memory SQLite database for each test file. Create helper functions for registering a test user and getting a token.
// test/helpers.ts
import { app } from '../src/index';
import request from 'supertest';
export async function createTestUser(overrides = {}) {
const userData = {
email: `test-${crypto.randomUUID()}@taskflow.app`,
password: 'testpassword123',
name: 'Test User',
...overrides,
};
const res = await request(app)
.post('/auth/register')
.send(userData);
return {
user: res.body.user,
token: res.body.token,
...userData,
};
}
export async function createTestProject(token: string, name = 'Test Project') {
const res = await request(app)
.post('/projects')
.set('Authorization', `Bearer ${token}`)
.send({ name });
return res.body.project;
}
Run the test suite. The terminal block below is an example of the target shape of a successful run; your counts and duration will vary:
✓ auth.test.ts (7 tests)
✓ projects.test.ts (6 tests)
✓ tasks.test.ts (10 tests)
✓ authorization.test.ts (5 tests)
Test Files 4 passed (4)
Tests 28 passed (28)
Duration 1.8s
Treat the displayed 28 passing tests as a tutorial target, not a recorded benchmark. If tests fail, determine whether the implementation or the assertion is wrong, make the appropriate fix, and re-run.
Pro Tip: Fix Failing Tests Critically
When AI-generated tests fail, don't blindly fix the test to match the code. Ask: is the code wrong or is the test wrong? A failing test may reveal either a faulty assumption or an implementation bug, so investigate both before accepting a change.
Security Audit
Before deploying anything, run a security-focused review. This is the checklist from Chapter 11 of the manual, applied to our specific codebase.
Perform a security audit on the complete Taskflow codebase.
Backend: [paste all server files]
Frontend: [paste all client files]
Check for:
- SQL injection vulnerabilities
- XSS in rendered content
- Hardcoded secrets or credentials
- Missing input validation
- Authentication bypasses
- Insecure dependencies
- Data exposure in API responses (e.g., returning password_hash)
Rate each finding as Critical, High, or Medium. Show the fix for each.
Example Audit Findings To Verify
If your audit confirms the critical example finding — password_hash exposed in API responses — fix it immediately: add a sanitizeUser function that strips password_hash before returning any user object.
// utils/sanitize.ts
import type { User } from '@taskflow/shared';
export function sanitizeUser(row: Record<string, unknown>): User {
const { password_hash, ...user } = row;
return user as User;
}
// Apply in auth routes:
// Before: res.json({ token, user })
// After: res.json({ token, user: sanitizeUser(user) })
Returning a database row that contains password_hash is a realistic failure mode and a useful audit case. Check your actual auth responses line by line; if they include password hashes, remove them before any deployment.
Deployment
For a weekend build, we want the simplest possible deployment. Two options, both prompt-driven:
Option A: Railway (Recommended)
Prepare the Taskflow app for deployment to Railway.
Current structure: monorepo with /client (Vite + React) and /server (Express + SQLite).
I need:
1. Production build script for the client (outputs to /server/public)
2. Express serves the static frontend in production
3. Environment variables: JWT_SECRET, NODE_ENV, PORT
4. CORS updated to allow the production domain
5. SQLite database file persists in a Railway volume
6. Dockerfile or railway.json config
// server/src/index.ts — production static serving
import path from 'path';
if (process.env.NODE_ENV === 'production') {
app.use(express.static(path.join(__dirname, '../public')));
// SPA fallback: serve index.html for all non-API routes
app.get('*', (req, res, next) => {
if (req.path.startsWith('/auth') || req.path.startsWith('/projects') || req.path.startsWith('/tasks')) {
return next();
}
res.sendFile(path.join(__dirname, '../public/index.html'));
});
}
Option B: VPS with Docker
If you prefer a VPS, ask AI to generate a Dockerfile and docker-compose.yml. The same build process applies — client builds to static files, server serves them. Add a reverse proxy (Caddy is simplest) for HTTPS.
The following deployment output is illustrative. Run the equivalent build and deploy commands for your chosen host, then record your own URL and checks.
-- Building client...
-- Client built to server/public (480KB)
-- Building server...
-- Server built to server/dist
$ railway up
-- Deployed to https://taskflow-abc123.railway.app
Demo vs Production: Draw the Line
A weekend build can be deployable without being production-grade in every dimension. Make the boundary explicit so you know what is "good enough for demo" versus what is required before real customer traffic.
Demo Gate (Verify Before Sharing)
Production-Required (Before Real Users)
Demo deployment is for feedback and learning. Production deployment is a reliability and risk commitment. If you cannot confidently answer "yes" to every production-required item above, keep the launch labeled as beta/demo and limit exposure.
The Retrospective
Once you have completed and verified your build, take time for the Meta Loop from Chapter 19: what worked, what did not, and what you would do differently.
I followed the Taskflow tutorial using an AI-assisted workflow. Retrospective time:
1. What was the most valuable prompt or technique?
2. Where did AI waste the most time (wrong output, needed heavy editing)?
3. What should I add to my personal prompt library?
4. If I started this project over, what would I do differently?
Most valuable: The Design → Critique step in Part 1 can surface risks such as password hash exposure, ordering decisions, and missing CORS before they become deployment blockers.
Most time wasted: The drag-and-drop integration. AI-generated DnD code often has subtle bugs with drop zone detection and position calculation. This required the most manual debugging. Next time: start with a minimal DnD prototype, test it works, then integrate into the full board.
Save to prompt library: The authFetch helper pattern, the security audit prompt, and the "fix top 5, leave the rest" refactor prompt.
Differently: Define the /auth/me endpoint in Part 1 instead of discovering it during frontend implementation. More generally: walk through the frontend component list in planning and identify every API endpoint they'll need — not just the CRUD endpoints.
A retrospective captures what to repeat, what to change, and which checks belong in the next project. Reviewing those notes over multiple builds can improve your workflow without pretending that every mistake is preventable.
Weekend Complete
The tutorial's target outcome is a locally verified Taskflow implementation and, if you complete the deployment checks, a limited demo deployment. Your time, test count, security findings, and deployment result depend on what you implement and verify.
The durable methodology is: design before code, critique before implementation, review before sharing — with AI assisting and you verifying each result.
That is the AI-assisted workflow this tutorial is designed to practice.
Complete Tutorial — Target Scope
- Full-stack app: React 18 + TypeScript + Tailwind frontend, Express + SQLite backend
- JWT authentication with bcrypt, protected routes, token persistence
- Projects with CRUD, soft-delete archiving, and ownership control
- Tasks with CRUD, kanban status management, and float-based positioning
- Drag-and-drop kanban board with optimistic updates
- Filtering by text search, priority, and assignee
- Toast notifications, responsive design, keyboard shortcuts
- 28 API tests covering auth, CRUD, authorization, and edge cases
- Security review: check for password hash exposure and address confirmed findings
- Demo deployment path with static file serving and environment configuration to verify