299ad7d943
Co-authored-by: Copilot <copilot@github.com>
99 lines
4.7 KiB
Markdown
99 lines
4.7 KiB
Markdown
# 6. Runtime View
|
|
|
|
Describes concrete behavior and interactions of the system's building blocks in form of scenarios from the following areas:
|
|
|
|
- Important use cases or features: how do building blocks execute them?
|
|
- Interactions at critical external interfaces: how do building blocks cooperate with users and neighboring systems?
|
|
- Operation and administration: launch, start-up, stop
|
|
- Error and exception scenarios
|
|
|
|
## Scenario 1: User Authentication
|
|
|
|
1. User submits login form in Flask frontend
|
|
2. Flask POSTs credentials to `POST /auth/login`
|
|
3. Auth Service validates credentials against DuckDB
|
|
4. Auth Service returns JWT token
|
|
5. Flask stores token in session cookie
|
|
6. User is redirected to dashboard
|
|
|
|
## Scenario 2: AI Text Generation
|
|
|
|
1. User fills in text generation form in Flask frontend
|
|
2. Flask POSTs prompt + model to `POST /generate/text` with JWT header
|
|
3. Auth Service validates JWT
|
|
4. AI Service sends prompt to openrouter.ai
|
|
5. openrouter.ai returns generated text
|
|
6. FastAPI returns result to Flask
|
|
7. Flask renders result page for user
|
|
|
|
## Scenario 3: Image Generation
|
|
|
|
1. User submits image generation form with prompt, model, size, aspect ratio, and resolution
|
|
2. Flask POSTs to `POST /generate/image` with JWT header
|
|
3. Router auto-detects model type:
|
|
- **FLUX / GPT-5 Image Mini**: calls `/chat/completions` with `modalities: ["image"]` and `image_config`
|
|
- **DALL-E 3**: calls `/images/generations` with `size` and `n`
|
|
4. Image URL (base64 data URL or hosted URL) returned to Flask
|
|
5. Flask renders page with generated image(s)
|
|
|
|
## Scenario 3a: Image Generation with Aspect Ratio & Resolution
|
|
|
|
1. User selects aspect ratio (e.g. `16:9`) and resolution (`2K`) on the image generation form
|
|
2. Flask POSTs `aspect_ratio` and `image_size` to `POST /generate/image`
|
|
3. Backend passes these as `image_config` to the chat completions endpoint (for FLUX/GPT-5 Image Mini)
|
|
4. Generated image respects the requested aspect ratio and resolution
|
|
|
|
## Scenario 4: Video Generation (Text-to-Video)
|
|
|
|
1. User submits video generation form with prompt, model, aspect ratio, resolution, and duration
|
|
2. Flask POSTs to `POST /generate/video` with JWT header
|
|
3. Auth Service validates JWT
|
|
4. Backend inserts a row into `generated_videos` with `status: "queued"` and returns the DB job ID
|
|
5. Flask renders result page with polling UI
|
|
6. Background worker (`video_worker.py`) picks up queued jobs every 15 seconds:
|
|
- Calls OpenRouter `POST /api/v1/videos` with model, prompt, and parameters
|
|
- Receives `{"id": "...", "polling_url": "..."}` and updates the DB row to `status: "processing"`
|
|
- Polls the `polling_url` every 15 seconds until `status` is `"completed"` or `"failed"`
|
|
- Updates the DB row with the final status and video URL
|
|
7. Frontend JavaScript polls `GET /generate/video/{db_id}/status` every 5 seconds
|
|
8. When `status` becomes `"completed"`, the response includes `video_url` — the video is displayed in a `<video>` element
|
|
9. If `status` becomes `"failed"`, an error message is shown
|
|
10. User can click "Cancel Job" to mark the job as `"cancelled"` (stops local polling, does not stop the provider job)
|
|
|
|
## Scenario 4a: Video Generation (Image-to-Video)
|
|
|
|
1. User provides an image URL, motion prompt, model, aspect ratio, resolution, and duration
|
|
2. Flask POSTs to `POST /generate/video/from-image` with JWT header
|
|
3. Same background worker flow as Scenario 4, with `generation_type: "image_to_video"`
|
|
|
|
## Scenario 4b: Video Job Cancellation
|
|
|
|
1. User clicks "Cancel Job" on the video detail page or gallery pending card
|
|
2. Frontend POSTs to `/generate/video/{id}/cancel`
|
|
3. Backend verifies the job belongs to the user and is not in a terminal state
|
|
4. Backend updates the DB row `status` to `"cancelled"`
|
|
5. Frontend stops polling and updates the UI to show "Job cancelled"
|
|
|
|
## Scenario 5: Token Refresh
|
|
|
|
1. Access token expires (TTL 15 min)
|
|
2. Client POSTs current refresh token to `POST /auth/refresh`
|
|
3. Auth Service validates JTI against `refresh_tokens` table (not revoked, not expired)
|
|
4. Old JTI is revoked; new JTI inserted into `refresh_tokens`
|
|
5. New access token + new refresh token returned to client
|
|
|
|
## Scenario 6: Admin User Management
|
|
|
|
1. Admin logs in and receives access token with `role: admin`
|
|
2. Admin GETs `/admin/stats` to view user and token counts
|
|
3. Admin DELETEs `/users/{id}` to remove a user — refresh tokens for that user are cascade-deleted
|
|
4. Admin PUTs `/users/{id}/role` to promote a user to admin or demote to user
|
|
|
|
## Scenario 7: User Profile Update
|
|
|
|
1. Authenticated user navigates to `/users/profile`
|
|
2. User submits updated email and/or new password
|
|
3. Flask POSTs to `PUT /users/me` with JWT header
|
|
4. Auth Service validates credentials and updates user record in DuckDB
|
|
5. Session `user_email` is updated; user sees success message
|