@studyportals/sp-connect-backend-contracts 0.0.0-stage → 1.0.0-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,15 @@
1
- # Temporary Holding Version
1
+ # @studyportals/sp-connect-backend-contracts
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Request and response types, error codes and business rules for the SP Connect API, published
4
+ from the backend repository so that clients and the service cannot drift apart. The package has
5
+ no runtime dependencies: it contains TypeScript types and constants only.
6
+
7
+ ```ts
8
+ import {
9
+ QUESTION_TEXT_MAX_LENGTH,
10
+ QuestionErrorCode,
11
+ } from '@studyportals/sp-connect-backend-contracts';
12
+ import type { SubmitQuestionRequest } from '@studyportals/sp-connect-backend-contracts';
13
+ ```
14
+
15
+ This package contains no client: it describes the payloads, not how to send them.
@@ -0,0 +1,3 @@
1
+ /** Stable public route constants. */
2
+ export declare const API_PREFIX = "api";
3
+ export declare const API_VERSION = "1";
@@ -0,0 +1,3 @@
1
+ /** Stable public route constants. */
2
+ export const API_PREFIX = 'api';
3
+ export const API_VERSION = '1';
@@ -0,0 +1,15 @@
1
+ /** Error codes the API returns that no module owns; module codes live in each module's contracts. */
2
+ export declare const ErrorCode: {
3
+ readonly Internal: "internal_error";
4
+ readonly InvalidRequestBody: "request.invalid_body";
5
+ };
6
+ export type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
7
+ /**
8
+ * `{ code, message, details? }` body of the API's own errors. Nest's built-in HTTP errors, such as
9
+ * a 401 from the auth guard, keep Nest's `{ statusCode, message, error }` body instead.
10
+ */
11
+ export interface ErrorResponse {
12
+ readonly code: string;
13
+ readonly message: string;
14
+ readonly details?: Record<string, string | number | boolean>;
15
+ }
@@ -0,0 +1,5 @@
1
+ /** Error codes the API returns that no module owns; module codes live in each module's contracts. */
2
+ export const ErrorCode = {
3
+ Internal: 'internal_error',
4
+ InvalidRequestBody: 'request.invalid_body',
5
+ };
@@ -0,0 +1,8 @@
1
+ export { API_PREFIX, API_VERSION } from './config/routes.js';
2
+ export { ErrorCode } from './errors.js';
3
+ export type { ErrorResponse } from './errors.js';
4
+ export { ROLES } from './roles.js';
5
+ export type { Role } from './roles.js';
6
+ export type { CognitoPoolResponse } from '../modules/auth/contracts/cognito-pool.js';
7
+ export { EXTERNAL_ID_MAX_LENGTH, EXTERNAL_ID_PATTERN, QUESTION_TEXT_MAX_LENGTH, QUESTION_TEXT_MIN_LENGTH, QuestionErrorCode, } from '../modules/questions/contracts/question-rules.js';
8
+ export type { SubmitQuestionRequest, SubmitQuestionResponse, } from '../modules/questions/contracts/submit-question.js';
@@ -0,0 +1,4 @@
1
+ export { API_PREFIX, API_VERSION } from './config/routes.js';
2
+ export { ErrorCode } from './errors.js';
3
+ export { ROLES } from './roles.js';
4
+ export { EXTERNAL_ID_MAX_LENGTH, EXTERNAL_ID_PATTERN, QUESTION_TEXT_MAX_LENGTH, QUESTION_TEXT_MIN_LENGTH, QuestionErrorCode, } from '../modules/questions/contracts/question-rules.js';
@@ -0,0 +1,2 @@
1
+ export declare const ROLES: readonly ["student", "expert", "admin"];
2
+ export type Role = (typeof ROLES)[number];
@@ -0,0 +1 @@
1
+ export const ROLES = ['student', 'expert', 'admin'];
@@ -0,0 +1,4 @@
1
+ export interface CognitoPoolResponse {
2
+ readonly userPoolId: string;
3
+ readonly userPoolClientId: string;
4
+ }
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,2 @@
1
+ export { EXTERNAL_ID_MAX_LENGTH, EXTERNAL_ID_PATTERN, QUESTION_TEXT_MAX_LENGTH, QUESTION_TEXT_MIN_LENGTH, } from '../domain/question-constraints.js';
2
+ export { QuestionErrorCode } from '../domain/question-error-codes.js';
@@ -0,0 +1,2 @@
1
+ export { EXTERNAL_ID_MAX_LENGTH, EXTERNAL_ID_PATTERN, QUESTION_TEXT_MAX_LENGTH, QUESTION_TEXT_MIN_LENGTH, } from '../domain/question-constraints.js';
2
+ export { QuestionErrorCode } from '../domain/question-error-codes.js';
@@ -0,0 +1,11 @@
1
+ /** Public request and response shapes owned and published by the questions module. */
2
+ export interface SubmitQuestionRequest {
3
+ /** Up to `EXTERNAL_ID_MAX_LENGTH` characters matching `EXTERNAL_ID_PATTERN`. */
4
+ readonly programmeId: string;
5
+ /** `QUESTION_TEXT_MIN_LENGTH` to `QUESTION_TEXT_MAX_LENGTH` characters after trimming. */
6
+ readonly questionText: string;
7
+ }
8
+ export interface SubmitQuestionResponse {
9
+ /** A UUID. */
10
+ readonly questionId: string;
11
+ }
@@ -0,0 +1,4 @@
1
+ export declare const EXTERNAL_ID_MAX_LENGTH = 128;
2
+ export declare const EXTERNAL_ID_PATTERN: RegExp;
3
+ export declare const QUESTION_TEXT_MIN_LENGTH = 10;
4
+ export declare const QUESTION_TEXT_MAX_LENGTH = 280;
@@ -0,0 +1,4 @@
1
+ export const EXTERNAL_ID_MAX_LENGTH = 128;
2
+ export const EXTERNAL_ID_PATTERN = /^[A-Za-z0-9._:-]+$/;
3
+ export const QUESTION_TEXT_MIN_LENGTH = 10;
4
+ export const QUESTION_TEXT_MAX_LENGTH = 280;
@@ -0,0 +1,8 @@
1
+ export declare const QuestionErrorCode: {
2
+ readonly InvalidId: "question.invalid_id";
3
+ readonly InvalidProgrammeId: "question.invalid_programme_id";
4
+ readonly InvalidStudentId: "question.invalid_student_id";
5
+ readonly InvalidText: "question.invalid_text";
6
+ readonly ProgrammeNotFound: "question.programme_not_found";
7
+ };
8
+ export type QuestionErrorCode = (typeof QuestionErrorCode)[keyof typeof QuestionErrorCode];
@@ -0,0 +1,7 @@
1
+ export const QuestionErrorCode = {
2
+ InvalidId: 'question.invalid_id',
3
+ InvalidProgrammeId: 'question.invalid_programme_id',
4
+ InvalidStudentId: 'question.invalid_student_id',
5
+ InvalidText: 'question.invalid_text',
6
+ ProgrammeNotFound: 'question.programme_not_found',
7
+ };
package/package.json CHANGED
@@ -1,6 +1,24 @@
1
1
  {
2
2
  "name": "@studyportals/sp-connect-backend-contracts",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0-beta.1",
4
+ "description": "Public API contracts and business rules of the SP Connect backend.",
5
+ "license": "UNLICENSED",
6
+ "type": "module",
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/contracts/index.d.ts",
13
+ "import": "./dist/contracts/index.js"
14
+ }
15
+ },
16
+ "files": [
17
+ "dist",
18
+ "!dist/*.tgz"
19
+ ],
20
+ "sideEffects": false,
21
+ "engines": {
22
+ "node": ">=20"
23
+ }
24
+ }