nextcloud.url (or NEXTCLOUD_URL) names the site's Nextcloud. With it set, the address field is hidden and the page reads "Sign in with Nextcloud", with the app-password route underneath for whoever needs it; both routes use the default when no address is given. Without it, nothing changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dv6sqaY6Vq3ChZHMem3cnU
82 lines
4.9 KiB
JavaScript
82 lines
4.9 KiB
JavaScript
// ============================================================
|
|
// OPENAPI — what each endpoint is for
|
|
// ============================================================
|
|
// Paths and methods are read from the router (src/utils/openapi.js). This is
|
|
// the half introspection cannot supply: what an operation does, what it takes,
|
|
// and whether it needs a session.
|
|
//
|
|
// Keyed by "METHOD /path" exactly as the route is mounted, with :params left as
|
|
// they appear in the code. A route with no entry here fails test/openapi.test.js
|
|
// — that is the point. A new endpoint cannot ship without a sentence saying what
|
|
// it is, and an entry for an endpoint that no longer exists fails the same test
|
|
// from the other direction.
|
|
//
|
|
// `public: true` marks an operation that works with no session. Say it
|
|
// explicitly: guessing from middleware gets it wrong in the direction that
|
|
// hides a hole.
|
|
|
|
// Path parameters, described once rather than at every route that takes them.
|
|
var parameters = {
|
|
id: 'Identifier of the record, scoped to the signed-in account.',
|
|
workflow: 'Which feature the job belongs to (for example my_resources).',
|
|
key: 'Setting key, for example clinical_assistant.chat_model.',
|
|
slug: 'URL-safe name of the document.'
|
|
};
|
|
|
|
var operations = {
|
|
// ── Speech ──────────────────────────────────────────────────────────
|
|
'GET /api/nextcloud/config': {
|
|
summary: 'The site\'s Nextcloud address, if one is set',
|
|
description: 'nextcloud.url (or NEXTCLOUD_URL). When present the settings page hides the address field and the sign-in and app-password routes use it when none is given.'
|
|
},
|
|
'PUT /api/admin/config/tts/default': {
|
|
summary: 'Choose the default speech model and voice',
|
|
description: 'Sets tts.model and tts.voice together and puts the model on the speech roster (tts.roster) if it is not there. Refused when the model does not accept the voice; the error lists the voices it does accept.',
|
|
requestBody: { required: true, content: { 'application/json': { schema: { type: 'object', required: ['model'], properties: {
|
|
model: { type: 'string', description: 'Gateway model id, for example local-kokoro-tts.' },
|
|
voice: { type: 'string', description: 'A voice of that model. Omitted: its first voice.' }
|
|
} } } } }
|
|
},
|
|
// ── Session ─────────────────────────────────────────────────────────
|
|
'POST /api/auth/login': {
|
|
summary: 'Sign in with a password',
|
|
description: 'Returns a token and sets the ped_auth cookie. Rate limited.',
|
|
public: true
|
|
},
|
|
'POST /api/auth/register': {
|
|
summary: 'Create a local password account',
|
|
description: 'Refused while sign-in is SSO-only; accounts are then created at the SSO from an invitation link.',
|
|
public: true
|
|
},
|
|
'GET /api/auth/registration-status': {
|
|
summary: 'Whether local registration is open',
|
|
description: 'Read by the sign-in screen to decide whether to offer the register link.',
|
|
public: true
|
|
},
|
|
'POST /api/auth/logout': { summary: 'End this session' },
|
|
'GET /api/auth/me': { summary: 'The signed-in account' },
|
|
|
|
// ── Clinical assistant ──────────────────────────────────────────────
|
|
'POST /api/clinical-assistant/ask': {
|
|
summary: 'Ask a question against the clinical corpus',
|
|
description: 'Streams the answer as server-sent events, with the retrieved sources.'
|
|
},
|
|
|
|
// ── My Resources ────────────────────────────────────────────────────
|
|
'GET /api/my-resources': { summary: 'Teaching material belonging to this account' },
|
|
'GET /api/my-resources/:id': { summary: 'One saved resource' },
|
|
'POST /api/my-resources/generate': { summary: 'Generate a deck or handout' },
|
|
'POST /api/my-resources/:id/refine': { summary: 'Revise a saved resource' },
|
|
'GET /api/my-resources/:id/export': { summary: 'Download as PowerPoint, Word or PDF' },
|
|
'GET /api/my-resources/theme-sample/:id': {
|
|
summary: 'A sample deck in one theme',
|
|
description: 'Every slide layout with placeholder text, as a PowerPoint file, so a theme can be judged before it is used.'
|
|
},
|
|
'POST /api/my-resources/:id/to-nextcloud': { summary: 'Send the rendered file to the owner\'s Nextcloud' },
|
|
|
|
// ── Health ──────────────────────────────────────────────────────────
|
|
'GET /api/health': { summary: 'Liveness', public: true },
|
|
'GET /api/build': { summary: 'The revision this container is running', public: true }
|
|
};
|
|
|
|
module.exports = { operations: operations, parameters: parameters };
|