Owner: Engineering Team | Last Updated: 2026-01-30 | Status: Current
This document provides the C4 Level 2 (Container) view of the WWAI system, detailing every service, their communication protocols, port mappings, base URLs, and dependency relationships. This is the primary reference for understanding how services interact at runtime.
WWAI Service Map (C4 Level 2)
=============================
CLIENTS PLATFORM CORE EXTERNAL SERVICES
------- ------------- -----------------
+--------------------+
| Next.js Web App |
| Port: 3000 |
| URL: app.wwai.ai |----+
+--------------------+ |
| +--------------------------+ +-------------------+
+--------------------+ | | | | Google OAuth |
| Flutter Mobile App | | | Nginx / ALB | | accounts.google.. |
| iOS + Android |----+--->| Port: 443 (HTTPS) |---->| Protocol: OAuth2 |
+--------------------+ | | URL: *.wwai.ai | +-------------------+
| | |
+--------------------+ | +-----------+--------------+ +-------------------+
| Chrome Extension | | | | Facebook OAuth |
| Content Script + |----+ | HTTPS / TLS | facebook.com/v18 |
| Background Worker | | | | Protocol: OAuth2 |
+--------------------+ | | +-------------------+
| +-----------v--------------+
+--------------------+ | | | +-------------------+
| Shopify Plugin | | | Django REST API | | Stripe API |
| Embedded App |----+ | Port: 8000 |---->| api.stripe.com |
+--------------------+ | | URL: api.wwai.ai | | Protocol: REST |
| | Protocol: REST (JSON) | +-------------------+
+--------------------+ | | |
| WordPress Plugin |----+ | Endpoints: | +-------------------+
| PHP / REST Client | | /api/v1/humanize | | Churnkey |
+--------------------+ | /api/v1/detect |---->| api.churnkey.co |
| /api/v1/auth | | Protocol: REST |
| /api/v1/billing | +-------------------+
| /api/v1/user |
| /api/v1/admin | +-------------------+
| | | 9 AI Detectors |
+---------+---+---+--------+---->| (see table below) |
| | | | Protocol: REST |
| | | +-------------------+
+-------------+ | +------------+
| | |
+----------v------+ +-------v-------+ +----v-----------+
| | | | | |
| PostgreSQL | | Redis | | AWS S3 |
| Port: 5432 | | Port: 6379 | | s3.amazonaws.. |
| Protocol: TCP | | Protocol: TCP | | Protocol: HTTPS|
| | | | | |
| - Users | | - Sessions | | - Static assets|
| - Subscriptions | | - Rate limits | | - Model files |
| - Usage logs | | - Cache | | - Exports |
| - API keys | | - Queues | | |
+-----------------+ +---------------+ +----------------+
MICROSERVICES LAYER (planned — not in production)
--------------------------------------------------
The layer drawn below is the TARGET architecture. None of it is in the
request path today. Current production state on AWS:
- ALB still routes every request directly to Django REST API. The
gateway box does not exist as a routing hop.
- KrakenD has never been deployed. The `walter-go-plugin` Go-plugin
(.so) build has never been loaded into a KrakenD binary on staging
or preprod.
- The standalone Go middleware (`cmd/server/main.go` built via
`Dockerfile.middleware`) ships in the ECS task definitions for
`krakend-middleware-staging-walter` and
`krakend-middleware-preproduction-walter` and the containers stay
in RUNNING state, but the ALB target group does not point at them
and their logs are empty. The middleware is not on the traffic path.
- walter-job-service has never been deployed to AWS in any form.
No DNS record, no ECS task, no ALB listener.
- AI Humanizer / AI Detector remain owned by Django (in-process calls
through Django's task layer). The standalone-FastAPI form drawn in
the diagram is the post-extraction state, not the current state.
Client (Next.js / Mobile / Plugins)
|
| HTTPS (X-API-Key | Authorization: Bearer)
v
+---------------------------------------------------+
| KrakenD API Gateway (walter-go-plugin .so) | <-- not deployed
| Port: 8080 |
| - Auth: HGETALL apikey:{key} |
| - Scope check: any_of / all_of |
| - Billing: atomic Lua (→ Go WATCH+TxPipeline) |
| - Injects X-User-Id, X-Request-Cost downstream |
| - Strips X-API-Key / Authorization before fwd |
+-------+-----------------------+-------------------+
| |
| upstream fan-out | results channel
v v
+-----------------+ +--------------------------+
| Django REST API | | walter-job-service | <-- not deployed
| (existing, | | FastAPI, Tortoise ORM |
| reached | | Port: 8000 internal |
| directly today)| | URL: jobs.wwai.ai |
+-----------------+ | |
| Endpoints: |
+-----------------+ | GET /jobs/{id} (poll) |
| AI Humanizer |---| GET /jobs (list) |
| FastAPI / GPU | | WS /ws/jobs/{id} |
| (still in | | POST callback → client |
| Django today) | | |
+-----------------+ | |
| |
+-----------------+ | |
| AI Detector |---| Listens: Redis Pub/Sub |
| FastAPI / GPU | | job:* channel |
| (still in | +-----------+--------------+
| Django today) | |
+-----------------+ v
+--------------------------+
| PostgreSQL (jobs DB) | <-- not provisioned
| job_records, |
| callback_deliveries |
+--------------------------+
ARROWS (target state):
Client → KrakenD : sync HTTPS (api/humanizer, api/detector, ...)
KrakenD → Django / AI services : sync HTTPS with X-User-Id header
AI service → Redis (PUBLISH job:* : async event with job_id, status, result/error)
Job Service ← Redis (PSUBSCRIBE) : background listener consumes events
Client ↔ Job Service : polling, WebSocket, or webhook callback
MONITORING (Outbound from Web App & Backend)
------------------------------------------
+------------------+ +----------------+ +------------------+
| Sentry | | PostHog | | Google Analytics |
| sentry.io | | app.posthog.com| | (via GTM) |
| Protocol: HTTPS | | Protocol: HTTPS| | Protocol: HTTPS |
| Source: Web + | | Source: Web App| | Source: Web App |
| Backend | +----------------+ +------------------+
+------------------+
+----------------+ +------------------+
| MS Clarity | | AWS CloudWatch |
| clarity.ms | | Logs + Metrics |
| Protocol: HTTPS| | Protocol: AWS SDK|
| Source: Web App| | Source: ECS Tasks|
| (Prod only) | +------------------+
+----------------+
| Service | Technology | Port | Base URL | Protocol | Health Check | Status |
|---|---|---|---|---|---|---|
| Web Application | Next.js 16 / Node.js | 3000 | https://app.wwai.ai |
HTTPS | GET /api/health |
Current |
| Django REST API | Python / Django 5.x | 8000 | https://api.wwai.ai |
HTTPS (REST/JSON) | GET /api/v1/health |
Current |
| KrakenD API Gateway | KrakenD CE 2.5 + Go plugin (walter-go-plugin) |
8080 | https://api.wwai.ai (planned) |
HTTPS (REST + WS) | GET /__health |
Planned, not deployed. The walter-go-plugin repo also ships a standalone Go middleware (cmd/server) built via Dockerfile.middleware — that image is in the staging/preprod ECS task definitions but the ALB does not route to it; the container is dark. KrakenD itself has never been launched. |
| Job Service | Python / FastAPI + Tortoise ORM | 8000 (internal) | https://jobs.wwai.ai (planned) |
HTTPS (REST + WS) | GET /health |
Planned, not deployed. No ECS task, no ALB listener, no DNS record. |
| AI Humanizer | Python / FastAPI + GPU | 8000 (internal) | Internal | HTTPS (REST) | GET /health |
In-process inside Django today. Standalone FastAPI form is the post-extraction target — repo exists but is not yet built into an AWS deploy. |
| AI Detector | Python / FastAPI + GPU | 8000 (internal) | Internal | HTTPS (REST) | GET /health |
In-process inside Django today. Same status as AI Humanizer. |
| PostgreSQL | PostgreSQL 15+ | 5432 | Internal (AWS RDS) | TCP (pg wire) | pg_isready | Current |
| Job Service Postgres | PostgreSQL 16 | 5432 | Internal (containerised, separate DB) | TCP (pg wire) | pg_isready | Planned, not provisioned. |
| Redis (ElastiCache) | Redis 7+ | 6379 | Internal (ElastiCache, shared) | TCP (RESP) | PING |
Current — Django uses it for sessions, cache, and rate-limit counters. The new key namespaces (apikey:*, balance:*, job:*, pending_jobs:*) will be populated by KrakenD and Job Service once those services land; nothing writes to them today. |
| Service | Base URL | Protocol | Auth Method | Rate Limits |
|---|---|---|---|---|
| Google OAuth | https://accounts.google.com |
OAuth 2.0 / OIDC | Client ID + Secret | Google default |
| Facebook OAuth | https://graph.facebook.com/v18.0 |
OAuth 2.0 | App ID + Secret | Facebook default |
| Stripe | https://api.stripe.com/v1 |
REST (HTTPS) | Bearer token (Secret Key) | 100 req/s (live) |
| Churnkey | https://api.churnkey.co |
REST (HTTPS) | API Key | Per agreement |
| Sentry | https://<org>.ingest.sentry.io |
HTTPS | DSN | Unlimited |
| PostHog | https://app.posthog.com |
HTTPS | Project API Key | Per plan |
| Google Analytics | Via Google Tag Manager | HTTPS (JS) | Measurement ID | Unlimited |
| Microsoft Clarity | https://clarity.ms |
HTTPS (JS) | Project ID | Unlimited |
| AWS S3 | https://s3.<region>.amazonaws.com |
HTTPS (AWS SDK) | IAM Role / Access Key | 5,500 PUT/s per prefix |
| AWS CloudWatch | Regional endpoint | HTTPS (AWS SDK) | IAM Role | AWS default |
| # | Detector | Base URL | Auth Method | Response Format | Typical Latency |
|---|---|---|---|---|---|
| 1 | GPTzero | https://api.gptzero.me/v2 |
API Key (Header) | JSON | 2-5s |
| 2 | ZeroGPT | https://api.zerogpt.com/api |
API Key (Header) | JSON | 1-3s |
| 3 | Sapling | https://api.sapling.ai/api/v1 |
API Key (Query) | JSON | 1-2s |
| 4 | Copyleaks | https://api.copyleaks.com/v2 |
Bearer Token (OAuth) | JSON | 3-8s |
| 5 | Writer | https://api.writer.com/v1 |
API Key (Header) | JSON | 1-3s |
| 6 | Turnitin | https://api.turnitin.com/api/v1 |
API Key + Secret | JSON | 5-15s |
| 7 | Originality | https://api.originality.ai/api/v1 |
API Key (Header) | JSON | 2-4s |
| 8 | Crossplag | https://api.crossplag.com/v1 |
API Key (Header) | JSON | 2-5s |
| 9 | Content at Scale | https://api.contentatscale.ai/v1 |
API Key (Header) | JSON | 1-3s |
Note: Detector latencies are approximate and vary based on text length and service load. The backend calls detectors in parallel to minimize total response time.
All client applications communicate with the Django REST API over HTTPS using JSON payloads.
Client Request Flow:
====================
Client App ALB / Nginx Django API
---------- ----------- ----------
| | |
|-- HTTPS Request ------------>| |
| Headers: | |
| Authorization: Bearer <JWT> |
| Content-Type: application/json |
| X-Fingerprint: <device-fp> |
| X-Turnstile-Token: <captcha> |
| | |
| |-- HTTP (port 8000) ------>|
| | X-Forwarded-For: <ip> |
| | X-Real-IP: <ip> |
| | |
| |<-- JSON Response ---------|
|<-- HTTPS Response -----------| Status: 200/4xx/5xx |
| Body: JSON | |
Django API --> External Detectors (Parallel Fan-Out):
=====================================================
Django API
|
+--[async]--> GPTzero API ---------> Response
+--[async]--> ZeroGPT API ---------> Response
+--[async]--> Sapling API ---------> Response
+--[async]--> Copyleaks API --------> Response Aggregation
+--[async]--> Writer API ----------> Response ----> Engine ---> Client
+--[async]--> Turnitin API --------> Response
+--[async]--> Originality API -----> Response
+--[async]--> Crossplag API -------> Response
+--[async]--> Content at Scale API -> Response
KrakenD intercepts every request to /api/* before it reaches the upstream
service. The Go plugin (walter-middleware) does atomic auth + scope check +
billing in a single Lua call to Redis. On success it injects identity headers
for the upstream service to consume; the raw API key is stripped.
Client KrakenD + walter-go-plugin Redis (ElastiCache)
------ -------------------------- -------------------
| | |
| HTTPS request to | |
| /api/humanizer (X-API-Key: sk_...) | |
|-------------------------------------->| |
| | extract API key |
| | analyze body, count words |
| | calculate cost |
| | EVALSHA redis.lua (atomic): |
| |--------------------------------------->|
| | 1. HGETALL apikey:{key} |
| | 2. check status == active |
| | 3. validate scopes (any_of/all_of) |
| | 4. GET balance:{user_id} |
| | 5. check balance >= cost |
| | 6. SET balance:{user_id} new_balance |
| |<---------------------------------------|
| | result: {0, user_id, new_balance} |
| | |
| | strip X-API-Key, Authorization |
| | set X-User-Id, X-Request-Cost |
| | forward to upstream |
| | |
| +--------v--------+ |
| | Django / AI svc | |
| +--------+--------+ |
| | |
| | response |
| v |
|<--------------------------------------| |
| 200 OK + result |
Error codes returned by the Lua script:
Job Service is the single point of result delivery for async AI requests.
KrakenD creates the job (writes job:{id} HASH with callback_url and user_id);
the AI service publishes the result on Redis Pub/Sub; Job Service consumes
and dispatches to the client via polling, WebSocket, or callback.
Client KrakenD AI Humanizer/Detector Redis Job Service
------ ------- --------------------- ----- -----------
| | | | |
| POST /api/humanizer | | | |
| ?async=true | | | |
|----------------------->| | | |
| | auth + charge | | |
| | generate job_id | | |
| | HSET job:{id} | | |
| | callback_url=... | | |
| | user_id=... | | |
| |---------------------------- ------------->| |
| | proxy to AI service | | |
| |---------------------->| | |
| | 202 Accepted | | |
| |<----------------------| | |
|<-----------------------| | | |
| 202 {job_id} | | | |
| | | inference | |
| | | (seconds-minutes) | |
| | | PUBLISH job:{id} | |
| | | {status, result} | |
| | |------------------>| |
| | | | PSUBSCRIBE job:*|
| | | |---------------->|
| | | | | upsert JobRecord
| | | | | dispatch callback
| | |
| | |
| --- Delivery path A: polling --- |
| |
| GET /jobs/{job_id} (X-API-Key) |
|------------------------------------------------------------------------------------->|
| | HGETALL job:{id}
| | (fallback: Postgres)
|<-------------------------------------------------------------------------------------|
| 200 {status: "completed", result} |
| |
| --- Delivery path B: WebSocket --- |
| |
| WS /ws/jobs/{job_id}?token=... |
|<------------------------------------------------------------------------------------>|
| either: immediate result + close |
| or: wait up to 5 min on Redis Pub/Sub, then push result |
| |
| --- Delivery path C: webhook callback --- |
| |
| | POST {callback_url}
| | with {job_id, status, result}
| | exponential backoff:
| | 4s, 16s, 64s on failure
|<-------------------------------------------------------------------------------------|
| 2xx ack |
Job Service auth is independent of KrakenD: API Key via X-API-Key (validated against apikey:* in Redis, same source as KrakenD) or JWT via Authorization: Bearer. WebSocket cannot pass custom headers at handshake, so credentials go through ?token= query param. Callback URLs are validated against an SSRF blocklist before dispatch.
| Source | Direction | Endpoint | Events |
|---|---|---|---|
| Stripe | Stripe --> Backend | POST /api/v1/billing/webhooks/stripe |
checkout.session.completed, invoice.paid, invoice.payment_failed, customer.subscription.updated, customer.subscription.deleted |
| Churnkey | Churnkey --> Backend | POST /api/v1/billing/webhooks/churnkey |
cancellation.accepted, offer.accepted, session.completed |
| Shopify | Shopify --> Backend | POST /api/v1/integrations/shopify/webhook |
app/uninstalled, shop/update |
Dependency Direction: A --depends on--> B
=========================================
Next.js Web App
|--depends on--> Django REST API (all business logic)
|--depends on--> Google OAuth (social login)
|--depends on--> Facebook OAuth (social login)
|--depends on--> Sentry (error reporting)
|--depends on--> PostHog (analytics)
|--depends on--> Google Analytics via GTM (traffic)
|--depends on--> Microsoft Clarity (session replay)
|--depends on--> Stripe.js (client-side payments)
|--depends on--> Churnkey.js (cancellation flow)
|--depends on--> Cloudflare Turnstile (CAPTCHA)
|--depends on--> FingerprintJS (device fingerprint)
Flutter Mobile App
|--depends on--> Django REST API (all business logic)
|--depends on--> Google OAuth (social login)
|--depends on--> Facebook OAuth (social login)
Chrome Extension
|--depends on--> Django REST API (humanization + auth)
Shopify Plugin
|--depends on--> Django REST API (humanization)
|--depends on--> Shopify App Bridge (embedding)
WordPress Plugin
|--depends on--> Django REST API (humanization)
Django REST API
|--depends on--> PostgreSQL (persistent data)
|--depends on--> Redis (caching, rate limiting)
|--depends on--> AWS S3 (object storage)
|--depends on--> AI Humanization Models (text processing)
|--depends on--> AI Detection Models (scoring)
|--depends on--> Stripe API (payment processing)
|--depends on--> Churnkey API (churn prevention)
|--depends on--> 9x External Detectors (AI detection)
|--depends on--> Sentry (error reporting)
|--depends on--> AWS CloudWatch (logging)
KrakenD + walter-go-plugin (planned — not deployed)
|--depends on--> Redis (apikey:*, balance:*, idempotency keys, Lua script cache)
|--depends on--> Django REST API (upstream for /api/users, /api/api-keys, /api/scopes, /api/admin)
|--depends on--> AI Humanizer (upstream for /api/humanizer)
|--depends on--> AI Detector (upstream for /api/detector)
|--depends on--> Job Service (upstream for /jobs/*, /ws/jobs/*)
|--depends on--> Developer Portal microservice (sync source for apikey:* and user:* hashes)
|--depends on--> AWS Secrets Manager (env config: JWT_SECRET, REDIS_ADDR, BACKEND_URL)
walter-job-service (planned — not deployed)
|--depends on--> Redis (Pub/Sub job:* channel, job:{id} HASH, pending_jobs:{user_id})
|--depends on--> Job Service Postgres (job_records, callback_deliveries)
|--depends on--> Developer Portal microservice (sync source for apikey:* in Redis)
|--depends on--> Sentry (error reporting)
|--called by---> AI Humanizer (via Redis PUBLISH job:{id} after inference)
|--called by---> AI Detector (via Redis PUBLISH job:{id} after inference)
|--called by---> KrakenD (proxy of polling + WS endpoints)
|--posts to----> Client-supplied callback_url (webhook delivery)
AI Humanizer / AI Detector (standalone form is planned — currently in-process in Django)
|--depends on--> Redis (read job:{id} HASH for callback_url, PUBLISH result)
|--called by---> KrakenD (sync inference) and Django REST API (legacy path)
| Criticality | Services | Impact if Down |
|---|---|---|
| P0 - Critical | Django REST API, PostgreSQL, Redis. Once deployed: KrakenD (will become the single gateway for every authenticated request — failure = platform-wide outage). | Complete platform outage |
| P1 - High | AI Humanization Models, Stripe API. Once deployed: Job Service + Job Service Postgres (only delivery path for async AI results — failure means inferences complete but customers never receive them). | Core feature unavailable, payments blocked, or async results undelivered |
| P2 - Medium | External AI Detectors, AWS S3 | Degraded detection scoring, missing assets |
| P3 - Low | PostHog, Clarity, Google Analytics | No user-facing impact, analytics gap |
The system is designed to degrade gracefully when non-critical dependencies fail:
Individual Detector Failure: If one of the 9 external detectors times out or returns an error, the aggregated score is computed from the remaining detectors. The failed detector is noted in the response.
Analytics Service Failure: PostHog, Clarity, and GA failures are silently caught and do not affect user experience.
Churnkey Failure: If the cancellation flow SDK fails to load, users fall back to the standard Stripe cancellation flow.
Redis Failure: The backend falls back to database queries for cache misses. Rate limiting may become less precise during Redis outages.
KrakenD Failure (post-rollout): Once deployed, KrakenD will be on the hot path for every authenticated request — a full outage will be platform-wide. The fail_open plugin flag is declared in config but not wired through code; if shipped as-is, an ElastiCache outage would translate to total 503. Mitigation in design: per-endpoint circuit breakers (krakend-job-service-routing subtask), fallback to legacy direct-to-Django routing for non-billed endpoints, and standby instances in a second AZ.
Job Service Failure (post-rollout): Once deployed, async jobs cannot be delivered if Job Service is down, but the AI service still runs the inference (event sits unconsumed in Redis until Pub/Sub TTL or listener restart). Polling and WebSocket endpoints will return 503. Callback delivery is queued only for the lifetime of the listener instance — no durable retry store. Mitigation: clients should poll with backoff and treat missing events as recoverable.
| Port | Service | Environment | Notes |
|---|---|---|---|
| 443 | ALB / Nginx (HTTPS) | Production | TLS termination |
| 3000 | Next.js (HTTP) | Development / Internal | Behind ALB in production |
| 8000 | Django (HTTP) | Development / Internal | Behind ALB in production |
| 8080 | KrakenD API Gateway (planned) | Internal / behind ALB | Will replace direct ALB→Django routing once KrakenD is deployed. The standalone Go middleware image listens on this port inside its ECS container but the ALB target group does not point at it, so no traffic reaches it today. |
| 8000 | Job Service (planned) | Internal / behind ALB | FastAPI; same port number as Django but on a separate container, routed by KrakenD via jobs.wwai.ai host or /jobs//ws/jobs path. Not yet deployed. |
| 5432 | PostgreSQL | Internal only | AWS RDS, not publicly accessible |
| 5432 | Job Service Postgres (planned) | Internal only | Separate containerised PG instance, not shared with Django RDS. Not yet provisioned. |
| 6379 | Redis | Internal only | AWS ElastiCache, not publicly accessible; today used by Django (sessions/cache/rate limits). Once deployed, KrakenD and Job Service will share the same cluster on new key namespaces. |
The diagram above shows the target architecture. The sections below describe the order of work needed to actually get there. Each phase has its own teamwork task; cross-references link to those tasks for detailed sub-task breakdowns.
Status: blocked on infrastructure work.
Today the ECS services krakend-middleware-staging-walter and krakend-middleware-preproduction-walter ship the standalone Go binary built from Dockerfile.middleware. The ALB does not route to them and the containers' logs are empty. To activate the gateway:
Dockerfile.middleware to a KrakenD image that bundles the walter-go-plugin .so. The plugin must be built with the exact Go toolchain version that the KrakenD binary itself was compiled with — Go buildmode=plugin is strict about version matching.walter-go-plugin branch fix/audit-critical-findings (idempotency replay, refund on 5xx upstream, JSON text-field word count, BaseCost minimum, Lua hardening) before the plugin is ever exposed to public traffic.*.wwai.ai (or api.wwai.ai to start) to the KrakenD task group, with a fallback rule routing directly to Django so the cut-over can be staged path-by-path.apikey:* / user:* / balance:* synchronisation from the Developer Portal microservice into ElastiCache. The plugin reads these keys; the portal must be writing them in the expected schema.Related task: krakend-job-service-routing (covers ALB rules and KrakenD endpoint configuration). Dependencies: krakend-migration-deploy.
Status: planned, design captured.
The current walter-go-plugin/plugin/redis.lua is hard to test (no unit coverage), tightly coupled to a specific Redis version, and incompatible with ElastiCache cluster mode for multi-key operations. The replacement uses a HGETALL + GET + WATCH + TxPipeline flow in Go, with up to three retry attempts on redis.TxFailedErr.
A new GET /me endpoint is part of the same task: it validates an API key against Redis and returns user_id / scopes / key_prefix / status, without proxying to any backend. Zapier and similar integrations need this to introspect a key without consuming credits.
Related task: krakend-lua-to-go.
Status: planned, design captured.
The plugin was written before three large Developer Portal changes: SHA-256 hashing of API keys before Redis lookup, the plan/subscription state machine (trial → paid → expired), and internal scope definitions evaluated server-side. In the plugin's current form it cannot read keys that the portal writes. Sub-tasks:
apikey:{sha256(key)} and balance:{user_id} and to publish scope definitions.Related task: go-plugin-devportal-sync. Hard dependency on Phase A and Phase B.
Status: planned, code review complete.
Job Service exists in Microcervises/walter-job-service and has had its audit findings (JWT validation, migration shipping, callback 2xx semantics, ws/auth oracle, payload bug, compose secrets) merged in branch fix/audit-critical-findings. Deployment work:
docker-compose.yml in the repo is the deploy reference).aerich upgrade baked into the startup command (already done in the repo's Dockerfile).jobs.wwai.ai DNS record and an ALB listener routing to the new task group; once KrakenD is live (Phase A), move the routing rule into KrakenD instead.job:{id} Redis channel in the SDK format {job_id, status, result|error}. Until that publishing is live, the Job Service listener will have nothing to consume.Related tasks: job-service-integration, plus the walter-job-service-full-audit-c115985 follow-up list for any audit items not in the current branch.
Status: planned, not started.
The two inference paths currently live inside Django as in-process calls. Pulling them into standalone FastAPI services unlocks GPU-only deployments, independent autoscaling, and the publish-to-Redis flow that Job Service depends on. Cut-over plan:
walter-service-sdk) so each service emits the standardised PUBLISH job:{id} event after inference.tasks.py) from in-process inference to KrakenD-routed HTTPS — keep the legacy direct calls behind a feature flag for rollback.walter-backend entirely.Related tasks: ai-humanizer-sdk-integration, ai-detector-sdk-integration. Should not start before Phase A (otherwise the AI services have no gateway to be reached through).
Status: planned, trivial once Phase A is done.
The Dockerfile.middleware build, the cmd/server/main.go entry point, and the ECS task definitions that ship it are dead code once KrakenD is serving the same traffic. Delete the Dockerfile, drop the cmd/server directory from the walter-go-plugin repo, and remove the ECS services from Terraform / CDK. Tracked as cleanup; depends on Phase A having been stable for at least one full release cycle.
Phase A (KrakenD live)
|
+----> Phase B (Lua → Go)
| |
| +----> Phase C (Dev Portal sync)
|
+----> Phase E (extract AI services)
| |
| +----> Phase D (Job Service deploy)
|
+----> Phase F (remove standalone middleware)
Phase A is the gate for everything else. Phases B/C and Phases D/E can advance in parallel once A is in place. Phase F is cleanup that only makes sense after A is verified stable.
| Date | Author | Change |
|---|---|---|
| 2026-01-30 | Admin | Initial creation |
| 2026-05-18 | Admin | Added planned services: KrakenD API Gateway (walter-go-plugin) and Job Service (walter-job-service). Documented auth/billing flow through Lua script, async result delivery via polling/WebSocket/callback, dependency graph, criticality and graceful-degradation entries, and port mappings. |
| 2026-05-19 | Admin | Corrected wording about current production state: no KrakenD task is live on AWS, the standalone Go middleware in the walter-go-plugin repo is built and shipped to ECS but the ALB does not route to it (containers are dark), Job Service has never been deployed, and AI Humanizer/AI Detector remain in-process inside Django. All client traffic still flows ALB → Django directly. Added a Roadmap section with phases A–F describing the order of work to reach the target architecture. |
Prev: System Overview (C4 Level 1 - System Context) | Next: Security Architecture | Up: General