-
Notifications
You must be signed in to change notification settings - Fork 0
Phase 1 foundation and deployment gate #4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
83 commits
Select commit
Hold shift + click to select a range
c90e14b
chore(gitignore): ignore desktop build artifacts
adoumouangnamouemmanuel cd9c665
docs(readme): document desktop commands
adoumouangnamouemmanuel c89ba20
build(api): add sidecar packaging scripts
adoumouangnamouemmanuel 8ce0ba4
build(api): configure sidecar native assets
adoumouangnamouemmanuel d1790f7
build(api): package sidecar executable
adoumouangnamouemmanuel ec88a07
test(api): add sidecar smoke verifier
adoumouangnamouemmanuel d7784bc
feat(api): emit sidecar readiness payload
adoumouangnamouemmanuel b4affd2
test(api): cover sidecar health security
adoumouangnamouemmanuel a251269
feat(api): secure local sidecar health
adoumouangnamouemmanuel de7a5ae
build(desktop): add Tauri commands
adoumouangnamouemmanuel d34b591
build(desktop): lock Tauri dependencies
adoumouangnamouemmanuel b0033d8
build(desktop): define Tauri shell crate
adoumouangnamouemmanuel 373978f
build(desktop): add Tauri build script
adoumouangnamouemmanuel bed7634
build(desktop): add default capability set
adoumouangnamouemmanuel 1fc1c8d
style(desktop): add Windows app icon
adoumouangnamouemmanuel 5d99472
feat(desktop): launch hidden local sidecar
adoumouangnamouemmanuel 16afde4
build(desktop): add Tauri entry point
adoumouangnamouemmanuel 2c92fd0
build(desktop): configure Windows bundle
adoumouangnamouemmanuel 36897f2
build(web): add Tauri API dependency
adoumouangnamouemmanuel 80e6962
feat(web): show desktop sidecar status
adoumouangnamouemmanuel 6c773b1
feat(web): read desktop deployment status
adoumouangnamouemmanuel d32160c
feat(web): localize desktop status
adoumouangnamouemmanuel 155ec09
docs(roadmap): mark deployment spike progress
adoumouangnamouemmanuel 73c2b00
docs(adr): record sidecar packaging decision
adoumouangnamouemmanuel de7639d
docs(deployment): add phase 1 spike runbook
adoumouangnamouemmanuel 70a1208
chore(lint): ignore generated Tauri schemas
adoumouangnamouemmanuel aad5af7
build(root): add desktop scripts
adoumouangnamouemmanuel f68407d
chore(lint): include CommonJS configs
adoumouangnamouemmanuel dea21e9
build(db): update SQLite native dependency
adoumouangnamouemmanuel bbf3738
feat(db): add deployment probe migration
adoumouangnamouemmanuel 940076b
feat(db): export deployment helpers
adoumouangnamouemmanuel 1a7b0a5
build(pnpm): allow SQLite native build
adoumouangnamouemmanuel 43a7761
build(deps): update workspace lockfile
adoumouangnamouemmanuel 1754e45
docs(roadmap): complete deployment spike checklist
adoumouangnamouemmanuel b5fcbf2
feat(db): define foundation schema
adoumouangnamouemmanuel e109731
feat(db): add foundation migration
adoumouangnamouemmanuel 05bd77a
chore(db): add foundation migration snapshot
adoumouangnamouemmanuel 793ffb4
chore(db): update migration journal
adoumouangnamouemmanuel 55897c6
feat(db): add sqlite client helper
adoumouangnamouemmanuel 716fa89
feat(db): add tenant repository primitives
adoumouangnamouemmanuel 659dc73
feat(db): add foundation seed data
adoumouangnamouemmanuel d09f2aa
feat(db): add foundation seed command
adoumouangnamouemmanuel 39e7fba
test(db): cover foundation migration and tenancy
adoumouangnamouemmanuel 62c551a
test(db): add vitest config
adoumouangnamouemmanuel 728020f
feat(db): export foundation modules
adoumouangnamouemmanuel 0f46b89
chore(db): add seed and test scripts
adoumouangnamouemmanuel e77c73a
chore: wire db seed and tests
adoumouangnamouemmanuel 97211d5
docs(db): document foundation schema
adoumouangnamouemmanuel 8643eb3
docs: add database seed command
adoumouangnamouemmanuel fa44b0a
docs(roadmap): mark phase 1.3 complete
adoumouangnamouemmanuel 40bc121
chore(scripts): add git bash convenience wrappers
adoumouangnamouemmanuel 75e6666
test(api): make clean-clone api tests use source aliases
adoumouangnamouemmanuel d1ed14b
ci: enable coderabbit reviews on develop
adoumouangnamouemmanuel 5b3753f
chore(api): share sidecar capability header
adoumouangnamouemmanuel cbe0a91
security(api): require sidecar token in production
adoumouangnamouemmanuel 98cb32f
test(api): cover sidecar capability checks
adoumouangnamouemmanuel ded2706
fix(api): handle sidecar startup failures
adoumouangnamouemmanuel 3ea7500
fix(api): parse rust host tuple from version output
adoumouangnamouemmanuel 01affe9
fix(api): harden sidecar verification cleanup
adoumouangnamouemmanuel dcc056a
security(desktop): require secure sidecar token randomness
adoumouangnamouemmanuel 0039a1b
security(desktop): enable restrictive tauri csp
adoumouangnamouemmanuel 9b67339
fix(db): reject async transaction callbacks
adoumouangnamouemmanuel 8003213
test(db): guard transaction callback types
adoumouangnamouemmanuel 8055332
fix(db): make deployment marker idempotent
adoumouangnamouemmanuel abc8fe4
security(db): project safe user columns
adoumouangnamouemmanuel 556e669
fix(db): implement seed upgrade contract
adoumouangnamouemmanuel 29d2891
fix(db): enforce sqlite role and audit constraints
adoumouangnamouemmanuel 22c9d0b
test(db): cover migration and repository safeguards
adoumouangnamouemmanuel 30dec90
feat(db): apply committed sqlite migrations
adoumouangnamouemmanuel f6f2a55
chore(db): use sqlite migrator for db:migrate
adoumouangnamouemmanuel fb97272
fix(scripts): trust command exit status
adoumouangnamouemmanuel 1cb2953
docs(db): clarify schema metadata primary key
adoumouangnamouemmanuel 586f08e
docs(readme): align command descriptions
adoumouangnamouemmanuel 777093e
feat(db): add application migration helper
adoumouangnamouemmanuel c95ed07
chore(db): export application migrations
adoumouangnamouemmanuel a0d447f
chore(db): reuse application migration helper
adoumouangnamouemmanuel 2d76f46
test(db): cover application migration helper
adoumouangnamouemmanuel e1f75f4
fix(api): migrate sqlite before readiness
adoumouangnamouemmanuel ffabca5
test(api): cover startup migration readiness
adoumouangnamouemmanuel bd6037e
build(api): package sqlite migrations in sidecar
adoumouangnamouemmanuel a67ec9c
test(api): verify sidecar application tables
adoumouangnamouemmanuel d3fe76e
test(db): normalize migration path assertion
adoumouangnamouemmanuel 4c466ea
test(api): restore sqlite path env in startup test
adoumouangnamouemmanuel File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| reviews: | ||
| auto_review: | ||
| base_branches: | ||
| - develop |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| module.exports = { | ||
| assets: [ | ||
| 'node_modules/better-sqlite3/prebuilds/win32-x64.node', | ||
| '../../packages/db/migrations/sqlite/**/*', | ||
| ], | ||
| publicPackages: ['better-sqlite3'], | ||
| }; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,106 @@ | ||
| import { spawnSync } from 'node:child_process'; | ||
| import { mkdirSync } from 'node:fs'; | ||
| import { createRequire } from 'node:module'; | ||
| import { dirname, join, resolve } from 'node:path'; | ||
| import { fileURLToPath } from 'node:url'; | ||
| import { build } from 'esbuild'; | ||
|
|
||
| const require = createRequire(import.meta.url); | ||
| const scriptDir = dirname(fileURLToPath(import.meta.url)); | ||
| const packageRoot = resolve(scriptDir, '..'); | ||
| const workspaceRoot = resolve(packageRoot, '..', '..'); | ||
| const binariesDir = join(workspaceRoot, 'apps', 'desktop', 'src-tauri', 'binaries'); | ||
| const sidecarName = 'edutrack-api-sidecar'; | ||
| const pkgCliPath = require.resolve('@yao-pkg/pkg/lib-es5/bin.js'); | ||
| const bundledEntryPath = join(packageRoot, 'dist', 'sidecar.cjs'); | ||
| const pkgConfigPath = join(packageRoot, 'pkg.sidecar.config.cjs'); | ||
|
|
||
| const rustcVersion = commandOutput('rustc', ['-vV']); | ||
| const targetTriple = parseRustHostTriple(rustcVersion); | ||
|
|
||
| if (!targetTriple.endsWith('windows-msvc')) { | ||
| throw new Error( | ||
| `The Phase 1.2 sidecar spike currently targets Windows MSVC, got ${targetTriple}.` | ||
| ); | ||
| } | ||
|
|
||
| mkdirSync(binariesDir, { recursive: true }); | ||
|
|
||
| const outputPath = join(binariesDir, `${sidecarName}-${targetTriple}.exe`); | ||
|
|
||
| await build({ | ||
| entryPoints: [join(packageRoot, 'dist', 'index.js')], | ||
| bundle: true, | ||
| platform: 'node', | ||
| target: 'node24', | ||
| format: 'cjs', | ||
| external: ['better-sqlite3'], | ||
| outfile: bundledEntryPath, | ||
| logLevel: 'info', | ||
| logOverride: { | ||
| 'empty-import-meta': 'silent', | ||
| }, | ||
| }); | ||
|
|
||
| run(process.execPath, [ | ||
| pkgCliPath, | ||
| bundledEntryPath, | ||
| '--config', | ||
| pkgConfigPath, | ||
| '--targets', | ||
| 'node24-win-x64', | ||
| '--output', | ||
| outputPath, | ||
| ]); | ||
|
|
||
| console.log(`Built ${outputPath}`); | ||
|
|
||
| function commandOutput(command, args) { | ||
| const result = spawnSync(command, args, { | ||
| cwd: workspaceRoot, | ||
| encoding: 'utf8', | ||
| }); | ||
|
|
||
| if (result.status !== 0) { | ||
| throw new Error(commandFailureMessage(command, args, result)); | ||
| } | ||
|
|
||
| return result.stdout.trim(); | ||
| } | ||
|
|
||
| function run(command, args) { | ||
| const result = spawnSync(command, args, { | ||
| cwd: packageRoot, | ||
| stdio: 'inherit', | ||
| }); | ||
|
|
||
| if (result.status !== 0) { | ||
| throw new Error(commandFailureMessage(command, args, result)); | ||
| } | ||
| } | ||
|
|
||
| function parseRustHostTriple(rustcVersion) { | ||
| const hostLine = rustcVersion.split(/\r?\n/).find((line) => line.startsWith('host:')); | ||
|
|
||
| if (!hostLine) { | ||
| throw new Error('Could not determine the Rust host triple from rustc -vV output.'); | ||
| } | ||
|
|
||
| const hostTriple = hostLine.slice('host:'.length).trim(); | ||
|
|
||
| if (!hostTriple) { | ||
| throw new Error('Rust host triple was empty in rustc -vV output.'); | ||
| } | ||
|
|
||
| return hostTriple; | ||
| } | ||
|
|
||
| function commandFailureMessage(command, args, result) { | ||
| const invocation = `${command} ${args.join(' ')}`; | ||
|
|
||
| if (result.error) { | ||
| return `Command failed: ${invocation}\n${result.error.name}: ${result.error.message}`; | ||
| } | ||
|
|
||
| return result.stderr?.trim() || `Command failed: ${invocation}`; | ||
| } | ||
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.