Skip to content

feat: Phase 0 — Project Scaffolding#9

Merged
ed-morais merged 19 commits into
mainfrom
feat/scaffold
May 11, 2026
Merged

feat: Phase 0 — Project Scaffolding#9
ed-morais merged 19 commits into
mainfrom
feat/scaffold

Conversation

@ed-morais

Copy link
Copy Markdown
Owner

What was built

  • Django 5.1 + DRF backend with health check endpoint (GET /api/v1/health/)
  • Vite + React 18 (TypeScript) + Tailwind CSS frontend
  • Docker Compose with PostgreSQL 16 + Redis 7
  • CORS, JWT auth (SimpleJWT with token blacklist), environment variable loading
  • pytest configured: pytest-django, factory-boy, pytest-mock, freezegun, pytest-cov
  • Vitest + React Testing Library + MSW configured
  • Playwright E2E configured (Chromium)
  • GitHub Actions CI: backend (pytest + coverage) + frontend (Vitest + Playwright)

Tests

  • Backend: 19 unit tests passing (87% coverage)
  • Frontend: 1 unit test passing
  • E2E: 1 Playwright spec passing (homepage loads)
  • Functional test: test_user_visits_ima_and_sees_landing_page

How to test

# Backend
cd backend
source venv/Scripts/activate   # Windows; or: source venv/bin/activate on Linux/Mac
pytest -v

# Frontend
cd frontend
npm run test -- --run
npx playwright test

Known open items (non-blocking, addressed in Phase 1+)

  • conftest.py mock_ai fixture not fully configured (no AI code yet)
  • channels in INSTALLED_APPS but ProtocolTypeRouter not wired (Phase 5)
  • SECRET_KEY has insecure fallback default (hardened in prod config)

Closes #1

ed-morais added 19 commits May 10, 2026 16:21
- Scaffolded React TypeScript project with Vite
- Added Tailwind CSS via @tailwindcss/vite plugin
- Simplified App.tsx to minimal <h1>Ima</h1>
- Added @import tailwindcss to index.css
- App.test.tsx written (RED — Vitest not configured yet, Step 7)
- Created Django 5.1 project in backend/
- Installed DRF, django-cors-headers, simplejwt, dj-database-url,
  python-decouple, celery, channels, drf-spectacular, psycopg2-binary
- Created requirements.txt and requirements-test.txt
- Added test_health_check_returns_200 (RED — endpoint not yet implemented)
- PostgreSQL 16 Alpine on port 5432
- Redis 7 Alpine on port 6379
- Persistent volume for postgres data
- Verified both containers start successfully
- Load SECRET_KEY, DEBUG, ALLOWED_HOSTS, DATABASE_URL, REDIS_URL from env
- Added corsheaders, rest_framework, simplejwt, drf_spectacular, channels
- CorsMiddleware positioned before CommonMiddleware
- JWT: 60min access, 7-day refresh, ROTATE_REFRESH_TOKENS=True
- DATABASE_URL via dj-database-url, falls back to SQLite for dev
- AI provider settings (GEMINI_API_KEY, ANTHROPIC_API_KEY, OPENAI_API_KEY)
- Created pytest.ini with DJANGO_SETTINGS_MODULE
- Installed pytest, pytest-django, pytest-mock, factory-boy, freezegun, pytest-cov
- Created conftest.py with client, api_client, mock_ai fixtures
- Verified pytest collects 2 tests successfully
- Installed vitest@2.1, @testing-library/react, @testing-library/jest-dom,
  @testing-library/user-event, msw, happy-dom
- Downgraded to Vite 5.x + React 18 for Node 20.12 compatibility
  (Vite 8/Vitest 4 require Node 20.19+)
- Created vitest.config.ts with happy-dom environment and RTL setup
- Created src/test/setup.ts for @testing-library/jest-dom matchers
- App.test.tsx passes GREEN — renders without crashing
- Installed @playwright/test and Chromium browser
- Created playwright.config.ts with Chromium project and Vite webServer
- Created e2e/homepage.spec.ts testing root element visibility
- E2E test passes GREEN — homepage loads correctly
- Backend job: Python 3.10, PostgreSQL 16, Redis 7 services
- Backend runs pytest with coverage report (codecov upload)
- Frontend job: Node 20, npm ci, Vitest unit tests, Playwright E2E
- Triggers on push/PR to main branch
- Created HealthCheckView with no auth/permission requirements
- Added /api/v1/health/ URL route
- test_health_check_returns_200 now passes GREEN
- test_cors_headers_present_on_api_response passes GREEN
- Response format: {"data": {"status": "ok"}, "error": null}
Story: Developer verifies backend health check is reachable.
- Created functional_tests/base.py with FunctionalTest base class
- Created functional_tests/test_homepage.py with HomepageTest
- test_user_visits_ima_and_sees_landing_page passes GREEN:
  - GET /api/v1/health/ returns 200
  - Response data.status == "ok"
  - Response error == null
- Phase 0 scaffolding complete
…done

- All 11 steps completed
- functional_test_passing: true
- status: reviewing
- last_agent: dev
Vitest was picking up Playwright spec files in e2e/ and failing.
Added explicit exclude pattern to vitest.config.ts to prevent this.
- Added 'rest_framework_simplejwt.token_blacklist' to INSTALLED_APPS
- Ran migrations to create token_blacklist tables
- Added test_token_blacklist_app_is_installed to verify the fix
- Strengthened test_cors_headers_present_on_api_response to actually
  verify the Access-Control-Allow-Origin header value (R2 fix)
- Changed FunctionalTest base to use django.test.TestCase (Phase 0)
  instead of LiveServerTestCase; will upgrade to LiveServerTestCase
  when Playwright FTs are added in Phase 5
- HomepageTest now imports and inherits from FunctionalTest base class
  instead of directly from django.test.TestCase
Replaced vacuous 'document.body is truthy' assertion with a meaningful
DOM assertion: screen.getByRole('heading', { name: /ima/i }) so the
test will fail if the Ima heading is missing or the component throws.
- Response envelope shape: data key, error key, error is null, data.status=ok
- Authentication boundary: accessible without auth header
- Method handling: POST returns 405, HEAD returns 200
- INSTALLED_APPS sanity: corsheaders, rest_framework, drf_spectacular, channels
- Settings sanity: USE_TZ, JSON-only renderer, JWT rotation, JWT blacklist

All Q1–Q9 QA items resolved. Coverage: 87%.
Functional test confirmed passing:
test_user_visits_ima_and_sees_landing_page PASSED

Phase 0 PR: #9
@ed-morais
ed-morais merged commit f69ff63 into main May 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Phase 0: Project Scaffolding

1 participant