fix(ai): lessonUrl builder in one place; authoring follows core canView
- Learner links go through lessonUrl/courseUrl (src/web/urls.ts). - Generation, the studio course list and file listing require an authoring right and core canView, so a global author needs a grant for a restricted course. Contract requests 8 (global author in canView) and 9 (STC_AI_ALLOWED_BASE_URLS in AppConfig). Co-Authored-By: Claude Opus 5.5 <[email protected]>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
ead7327bb1
commit
f3ce2e34bf
@@ -57,5 +57,25 @@ Proposal: export these paths from `@stc/core` (e.g. `cachePaths(dataDir)`) so bo
|
||||
|
||||
## 7. Learner lesson URL
|
||||
|
||||
Citations carry `lessonId`; the assistant links them to `/c/<courseId>/<lessonId>` (a guess at WP-A's route). Proposal: a `lessonUrl(courseId, lessonId)`
|
||||
helper in `@stc/contracts/web` so WP-A owns the route shape.
|
||||
Citations carry `lessonId`; the assistant links them to `/c/<courseId>/<lessonId>`. Every such link goes through
|
||||
`lessonUrl(courseId, lessonId)` / `courseUrl(courseId)` in `packages/feature-ai/src/web/urls.ts` (also exported from
|
||||
`@stc/feature-ai/web`), so a different WP-A route is a one-line change. Proposal: move that helper into
|
||||
`@stc/contracts/web` so WP-A owns the route shape.
|
||||
|
||||
## 8. A global `author` role in core's `canView`
|
||||
|
||||
Generation and the studio file listing now require an authoring right (owner, the `author` role or a `course_authors`
|
||||
row) and core's `canView(user, course, acl, isAuthor)`. `canView` only knows per-course authors (`isAuthor`), so a user
|
||||
with the global `author` role cannot reach a `restricted` course without an ACL grant or a `course_authors` row.
|
||||
Spec section 6 allows author rights "on all courses or per course", and the studio branch (`feature-studio`
|
||||
`server/feature.ts:82-85`) currently grants the global role on every course. Proposal: core exports one
|
||||
`canAuthor(user, course, acl, isAuthor)` (or `canView` treats `roles.includes("author")` like `isAuthor`), and both
|
||||
the studio and the AI package call it. Until then the AI package follows core's `canView` (the stricter rule).
|
||||
|
||||
## 9. `STC_AI_ALLOWED_BASE_URLS` in `AppConfig`
|
||||
|
||||
Learners' own keys (BYOK) go only to `https://api.anthropic.com`, `https://api.openai.com/v1` or an origin on the
|
||||
allowlist (SSRF guard). The allowlist is `STC_AI_ALLOWED_BASE_URLS` (comma-separated exact origins) plus the admin
|
||||
setting `allowedBaseUrls` in the server AI config. `AppConfig` is frozen, so the package reads the variable from
|
||||
`process.env` (injectable through `aiFeature(ctx, { env })`). Proposal: add `aiAllowedBaseUrls: string[]` to
|
||||
`AppConfig` and `loadConfig`.
|
||||
|
||||
Reference in New Issue
Block a user