Skip to content

Commit 44ad667

Browse files
Merge pull request #8683 from sagemathinc/fix-exam-mode-20251216
frontend/registration tokens: improve exam mode
2 parents 2ae60e4 + b5b1fd8 commit 44ad667

File tree

18 files changed

+1264
-587
lines changed

18 files changed

+1264
-587
lines changed

src/AGENTS.md

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -42,14 +42,24 @@ This file provides guidance to Claude Code (claude.ai/code) and also Gemini CLI
4242
- `cd packages/[package] && pnpm build` - Build and compile a specific package
4343
- For packages/next and packages/static, run `cd packages/[package] && pnpm build-dev`
4444
- `cd packages/[package] && pnpm test` - Run tests for a specific package
45-
- To typecheck the frontend, it is best to run `cd packages/static && pnpm build` - this implicitly compiles the frontend and reports TypeScript errors
4645
- **IMPORTANT**: When modifying packages like `util` that other packages depend on, you must run `pnpm build` in the modified package before typechecking dependent packages
4746

4847
### Development
4948

5049
- **IMPORTANT**: Always run `prettier -w [filename]` immediately after editing any .ts, .tsx, .md, or .json file to ensure consistent styling
51-
- After TypeScript or `*.tsx` changes, run `pnpm build` in the relevant package directory
52-
- When editing the frontend, run `pnpm build-dev` in `packages/static` (this implicitly builds the frontend)
50+
51+
#### When Working on Frontend Code
52+
53+
After making changes to files in `packages/frontend`:
54+
55+
1. **Typecheck**: Run `cd packages/frontend && pnpm tsc --noEmit` to check for TypeScript errors
56+
2. **Build**: Run `cd packages/static && pnpm build-dev` to compile the frontend for testing
57+
58+
**DO NOT** run `pnpm build` in `packages/frontend` - it won't work as expected for frontend development.
59+
60+
#### When Working on Other Packages
61+
62+
- After TypeScript changes, run `pnpm build` in the relevant package directory
5363

5464
## Architecture Overview
5565

@@ -155,11 +165,11 @@ CoCalc is organized as a monorepo with key packages:
155165

156166
### Development Workflow
157167

158-
1. Changes to TypeScript require compilation (`pnpm build` in relevant package)
159-
2. Database must be running before starting hub
160-
3. Hub coordinates all services and should be restarted after changes
161-
4. Use `pnpm clean && pnpm build-dev` when switching branches or after major changes
162-
5. **IMPORTANT**: After any frontend code changes, run `pnpm build-dev` in the `packages/static` directory to compile the frontend
168+
1. **Frontend changes**: After editing `packages/frontend`, typecheck with `cd packages/frontend && pnpm tsc --noEmit`, then build with `cd packages/static && pnpm build-dev`
169+
2. **Other package changes**: After TypeScript changes, run `pnpm build` in the relevant package directory
170+
3. Database must be running before starting hub
171+
4. Hub coordinates all services and should be restarted after changes
172+
5. Use `pnpm clean && pnpm build-dev` when switching branches or after major changes
163173

164174
# Workflow
165175

src/packages/database/postgres/site-license/hook.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const LAST_USED: { [license_id: string]: number } = {};
7171
export async function site_license_hook(
7272
db: PostgreSQL,
7373
project_id: string,
74-
paygoActive: boolean
74+
paygoActive: boolean,
7575
): Promise<void> {
7676
try {
7777
const slh = new SiteLicenseHook(db, project_id, paygoActive);
@@ -174,7 +174,7 @@ class SiteLicenseHook {
174174
if (!isEqual(this.projectSiteLicenses, this.nextSiteLicense)) {
175175
// Now set the site license since something changed.
176176
dbg.info(
177-
`setup a modified site license=${JSON.stringify(this.nextSiteLicense)}`
177+
`setup a modified site license=${JSON.stringify(this.nextSiteLicense)}`,
178178
);
179179
await query({
180180
db: this.db,
@@ -246,19 +246,19 @@ class SiteLicenseHook {
246246
const val = validLicenses.get(id).toJS();
247247
const key = licenseToGroupKey(val);
248248
return ORDERING_GROUP_KEYS.indexOf(key);
249-
})
249+
}),
250250
);
251251
}
252252

253253
return orderedIds;
254254
}
255255

256-
private computeQuotas(licenses) {
256+
private computeQuotas(licenses: SiteLicenses) {
257257
return compute_total_quota_with_reasons(
258258
this.project.settings,
259259
this.project.users,
260260
licenses,
261-
this.site_settings
261+
this.site_settings,
262262
);
263263
}
264264

@@ -301,19 +301,19 @@ class SiteLicenseHook {
301301
this.dbg.silly(`run_quota=${JSON.stringify(run_quota)}`);
302302
this.dbg.silly(
303303
`run_quota_with_license=${JSON.stringify(
304-
run_quota_with_license
305-
)} | reason=${JSON.stringify(newReasons)}`
304+
run_quota_with_license,
305+
)} | reason=${JSON.stringify(newReasons)}`,
306306
);
307307
if (!isEqual(run_quota, run_quota_with_license)) {
308308
this.dbg.info(
309309
`License "${license_id}" provides an effective upgrade ${JSON.stringify(
310-
upgrades
311-
)}.`
310+
upgrades,
311+
)}.`,
312312
);
313313
nextLicense[license_id] = { ...upgrades, status: "active" };
314314
} else {
315315
this.dbg.info(
316-
`Found a valid license "${license_id}", but it provides nothing new so not using it (reason: ${newReasons[license_id]})`
316+
`Found a valid license "${license_id}", but it provides nothing new so not using it (reason: ${newReasons[license_id]})`,
317317
);
318318
nextLicense[license_id] = {
319319
status: "ineffective",
@@ -366,7 +366,7 @@ class SiteLicenseHook {
366366
*/
367367
private async checkLicense({ license, license_id }): Promise<LicenseStatus> {
368368
this.dbg.info(
369-
`considering license ${license_id}: ${JSON.stringify(license?.toJS())}`
369+
`considering license ${license_id}: ${JSON.stringify(license?.toJS())}`,
370370
);
371371
if (license == null) {
372372
this.dbg.info(`License "${license_id}" does not exist.`);
@@ -380,12 +380,12 @@ class SiteLicenseHook {
380380
return "expired";
381381
} else if (activates == null || activates > new Date()) {
382382
this.dbg.info(
383-
`License "${license_id}" has not been explicitly activated yet ${activates}.`
383+
`License "${license_id}" has not been explicitly activated yet ${activates}.`,
384384
);
385385
return "future";
386386
} else if (await this.aboveRunLimit(run_limit, license_id)) {
387387
this.dbg.info(
388-
`License "${license_id}" won't be applied since it would exceed the run limit ${run_limit}.`
388+
`License "${license_id}" won't be applied since it would exceed the run limit ${run_limit}.`,
389389
);
390390
return "exhausted";
391391
} else {
@@ -420,7 +420,7 @@ class SiteLicenseHook {
420420
if (typeof run_limit !== "number") return false;
421421
const usage = await number_of_running_projects_using_license(
422422
this.db,
423-
license_id
423+
license_id,
424424
);
425425
this.dbg.verbose(`run_limit=${run_limit} usage=${usage}`);
426426
return usage >= run_limit;

0 commit comments

Comments
 (0)