From cb35522f62b1b51ff36a420aef96537dac5454ca Mon Sep 17 00:00:00 2001 From: Alexis Salnikoff Date: Sat, 9 Aug 2025 23:00:57 +0200 Subject: [PATCH 1/7] Update README.md Signed-off-by: Alexis Salnikoff --- README.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index afe8d10..90c9f38 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ A dynamic backend system that automatically creates API endpoints, database tables, and validation schemas based on api call from frontend. +[Complete Documentation](https://salnika.github.io/phantom-api.dev/) + ## Features - **Dynamic API**: Single route `/api/:resource/:action` handles all operations @@ -42,9 +44,6 @@ A dynamic backend system that automatically creates API endpoints, database tabl │ └── data/ # SQLite database files ├── admin-interface/ # admin (React admin panel) ├── phantom-api/ # client (NPM package for frontend integration) -├── demo/ # Vite React demo application -├── website/ # Marketing website -├── public-doc/ # MkDocs documentation ├── ecosystem.config.js # PM2 process configuration ├── Dockerfile # Backend containerization └── docker-compose.yml # Multi-service orchestration From e5e15f3c3d3726ce9ee50d7dbdd9b2f513aa504f Mon Sep 17 00:00:00 2001 From: salnika Date: Sat, 9 Aug 2025 23:24:48 +0200 Subject: [PATCH 2/7] chore: rename workspace --- .github/workflows/release.yml | 2 ++ Dockerfile | 4 +++- package.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 365605b..200c6bc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -91,6 +91,8 @@ jobs: with: node-version: '20' registry-url: 'https://registry.npmjs.org' + - name: Enable Corepack and Yarn 4 + run: corepack enable && corepack prepare yarn@4.9.2 --activate - name: Install dependencies run: yarn install --immutable - name: Build package diff --git a/Dockerfile b/Dockerfile index 986b8c3..cff1eb4 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,7 +41,9 @@ COPY phantom-api-backend/ ./phantom-api-backend/ COPY admin-interface/ ./admin-interface/ # Build des projets nécessaires à l'image -ENV NODE_OPTIONS="--experimental-loader=./.pnp.loader.mjs" +# Utilise un chemin absolu pour le loader PnP, car les scripts workspace +# s'exécutent depuis le dossier du package (sinon ./ pointe vers le workspace) +ENV NODE_OPTIONS="--experimental-loader=/app/.pnp.loader.mjs" RUN yarn workspace phantom-api-backend build \ && yarn workspace admin-interface build diff --git a/package.json b/package.json index e19b278..ee0c378 100644 --- a/package.json +++ b/package.json @@ -41,4 +41,4 @@ "admin-interface", "public-doc" ] -} \ No newline at end of file +} From 3d1017f1daa8970750905c834169cd9ecc10a910 Mon Sep 17 00:00:00 2001 From: salnika Date: Sat, 9 Aug 2025 23:47:07 +0200 Subject: [PATCH 3/7] chore: rename workspace --- .github/workflows/release.yml | 4 +- .pnp.cjs | 94 +++++++++++++++++------------------ package.json | 2 +- phantom-api/package.json | 2 +- yarn.lock | 30 +++++------ 5 files changed, 66 insertions(+), 66 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 200c6bc..f1af624 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -80,7 +80,7 @@ jobs: publish-npm: name: Publish npm package (requires approval) - if: needs.prepare.outputs.PROJECT == 'phantom-api' + if: needs.prepare.outputs.PROJECT == 'phantom-api-client' runs-on: ubuntu-latest needs: [prepare, build] environment: release # configure environment protection to require manual approval @@ -96,7 +96,7 @@ jobs: - name: Install dependencies run: yarn install --immutable - name: Build package - run: yarn workspace phantom-api build + run: yarn workspace ${{ needs.prepare.outputs.PROJECT }} build - name: Publish to npm env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.pnp.cjs b/.pnp.cjs index abafa14..1b19346 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -19,7 +19,7 @@ const RAW_RUNTIME_STATE = "reference": "workspace:admin-interface"\ },\ {\ - "name": "phantom-api",\ + "name": "phantom-api-client",\ "reference": "workspace:phantom-api"\ },\ {\ @@ -36,8 +36,8 @@ const RAW_RUNTIME_STATE = "pnpZipBackend": "libzip",\ "fallbackExclusionList": [\ ["admin-interface", ["workspace:admin-interface"]],\ - ["phantom-api", ["workspace:phantom-api"]],\ ["phantom-api-backend", ["workspace:phantom-api-backend"]],\ + ["phantom-api-client", ["workspace:phantom-api"]],\ ["phantom-api-monorepo", ["workspace:."]],\ ["public-doc", ["workspace:public-doc"]]\ ],\ @@ -54,13 +54,13 @@ const RAW_RUNTIME_STATE = ["bcrypt", "npm:6.0.0"],\ ["chalk", "npm:4.1.2"],\ ["dotenv", "npm:17.0.1"],\ - ["knip", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:5.61.3"],\ + ["knip", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:5.61.3"],\ ["oxlint", "npm:1.5.0"],\ - ["phantom-api", "workspace:phantom-api"],\ + ["phantom-api-client", "workspace:phantom-api"],\ ["phantom-api-monorepo", "workspace:."],\ ["syncpack", "npm:13.0.4"],\ - ["typedoc", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:0.28.7"],\ - ["typedoc-plugin-markdown", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:4.7.0"],\ + ["typedoc", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:0.28.7"],\ + ["typedoc-plugin-markdown", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:4.7.0"],\ ["typescript", "patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"]\ ],\ "linkType": "SOFT"\ @@ -3473,7 +3473,7 @@ const RAW_RUNTIME_STATE = ["date-fns", "npm:4.1.0"],\ ["globals", "npm:16.3.0"],\ ["jsdom", "virtual:4253337b4cd30e157fb9d4ddb93d42b7428af1121c63f21457fca930fbd00d9ed15d11be45331f32e1dd585b11e6fb86d2599a3fe4a31802e79ec051db662869#npm:26.1.0"],\ - ["knip", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:5.61.3"],\ + ["knip", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:5.61.3"],\ ["lucide-react", "virtual:4253337b4cd30e157fb9d4ddb93d42b7428af1121c63f21457fca930fbd00d9ed15d11be45331f32e1dd585b11e6fb86d2599a3fe4a31802e79ec051db662869#npm:0.525.0"],\ ["oxlint", "npm:1.5.0"],\ ["pino", "npm:9.7.0"],\ @@ -6220,7 +6220,7 @@ const RAW_RUNTIME_STATE = ["strip-json-comments", "npm:5.0.2"],\ ["typescript", null],\ ["zod", "npm:3.25.74"],\ - ["zod-validation-error", "virtual:52c4e47a1af756c3581c016437724dd5a5e123197e605dce921a7b4af2b3533a11fae8e21384c44d753eea716bc74d9d7e456af9c6f0c8febe78a352dae48df9#npm:3.5.2"]\ + ["zod-validation-error", "virtual:aa6259b8503d49478c75bdf954304de1eeb552f83b6568d48b0d23d4e117945e0883c37f5f299a20a524c3b7f9d93bf26042037f77783fb50df340aedfd39bf6#npm:3.5.2"]\ ],\ "packagePeers": [\ "@types/node",\ @@ -6229,8 +6229,8 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "HARD"\ }],\ - ["virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:5.61.3", {\ - "packageLocation": "./.yarn/__virtual__/knip-virtual-52c4e47a1a/0/cache/knip-npm-5.61.3-faa1de9466-2f8abef328.zip/node_modules/knip/",\ + ["virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:5.61.3", {\ + "packageLocation": "./.yarn/__virtual__/knip-virtual-aa6259b850/0/cache/knip-npm-5.61.3-faa1de9466-2f8abef328.zip/node_modules/knip/",\ "packageDependencies": [\ ["@nodelib/fs.walk", "npm:1.2.8"],\ ["@types/node", "npm:24.0.10"],\ @@ -6239,7 +6239,7 @@ const RAW_RUNTIME_STATE = ["formatly", "npm:0.2.4"],\ ["jiti", "npm:2.4.2"],\ ["js-yaml", "npm:4.1.0"],\ - ["knip", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:5.61.3"],\ + ["knip", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:5.61.3"],\ ["minimist", "npm:1.2.8"],\ ["oxc-resolver", "npm:11.5.0"],\ ["picocolors", "npm:1.1.1"],\ @@ -6248,7 +6248,7 @@ const RAW_RUNTIME_STATE = ["strip-json-comments", "npm:5.0.2"],\ ["typescript", "patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"],\ ["zod", "npm:3.25.74"],\ - ["zod-validation-error", "virtual:52c4e47a1af756c3581c016437724dd5a5e123197e605dce921a7b4af2b3533a11fae8e21384c44d753eea716bc74d9d7e456af9c6f0c8febe78a352dae48df9#npm:3.5.2"]\ + ["zod-validation-error", "virtual:aa6259b8503d49478c75bdf954304de1eeb552f83b6568d48b0d23d4e117945e0883c37f5f299a20a524c3b7f9d93bf26042037f77783fb50df340aedfd39bf6#npm:3.5.2"]\ ],\ "packagePeers": [\ "@types/node",\ @@ -7391,24 +7391,6 @@ const RAW_RUNTIME_STATE = "linkType": "HARD"\ }]\ ]],\ - ["phantom-api", [\ - ["workspace:phantom-api", {\ - "packageLocation": "./phantom-api/",\ - "packageDependencies": [\ - ["@types/node", "npm:24.0.10"],\ - ["axios", "npm:1.10.0"],\ - ["chalk", "npm:4.1.2"],\ - ["commander", "npm:12.1.0"],\ - ["knip", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:5.61.3"],\ - ["oxlint", "npm:1.5.0"],\ - ["phantom-api", "workspace:phantom-api"],\ - ["typedoc", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:0.28.7"],\ - ["typedoc-plugin-markdown", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:4.7.0"],\ - ["typescript", "patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"]\ - ],\ - "linkType": "SOFT"\ - }]\ - ]],\ ["phantom-api-backend", [\ ["workspace:phantom-api-backend", {\ "packageLocation": "./phantom-api-backend/",\ @@ -7441,7 +7423,7 @@ const RAW_RUNTIME_STATE = ["express-validator", "npm:7.2.1"],\ ["helmet", "npm:8.1.0"],\ ["jsonwebtoken", "npm:9.0.2"],\ - ["knip", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:5.61.3"],\ + ["knip", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:5.61.3"],\ ["oxlint", "npm:1.5.0"],\ ["pg", "virtual:09e1a04afd45af093cd8c29b97ddf4d19df61499634c38d0af82bb90c3d7132ade4b7fe95e3fb270962602a48f0e33defa03b58e28d078240eaec795cfcd7520#npm:8.16.3"],\ ["phantom-api-backend", "workspace:phantom-api-backend"],\ @@ -7450,8 +7432,8 @@ const RAW_RUNTIME_STATE = ["redis", "npm:4.7.1"],\ ["supertest", "npm:7.1.1"],\ ["tsx", "npm:4.20.3"],\ - ["typedoc", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:0.28.7"],\ - ["typedoc-plugin-markdown", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:4.7.0"],\ + ["typedoc", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:0.28.7"],\ + ["typedoc-plugin-markdown", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:4.7.0"],\ ["typescript", "patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"],\ ["vitest", "virtual:09e1a04afd45af093cd8c29b97ddf4d19df61499634c38d0af82bb90c3d7132ade4b7fe95e3fb270962602a48f0e33defa03b58e28d078240eaec795cfcd7520#npm:3.2.4"],\ ["zod", "npm:3.25.74"]\ @@ -7459,6 +7441,24 @@ const RAW_RUNTIME_STATE = "linkType": "SOFT"\ }]\ ]],\ + ["phantom-api-client", [\ + ["workspace:phantom-api", {\ + "packageLocation": "./phantom-api/",\ + "packageDependencies": [\ + ["@types/node", "npm:24.0.10"],\ + ["axios", "npm:1.10.0"],\ + ["chalk", "npm:4.1.2"],\ + ["commander", "npm:12.1.0"],\ + ["knip", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:5.61.3"],\ + ["oxlint", "npm:1.5.0"],\ + ["phantom-api-client", "workspace:phantom-api"],\ + ["typedoc", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:0.28.7"],\ + ["typedoc-plugin-markdown", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:4.7.0"],\ + ["typescript", "patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"]\ + ],\ + "linkType": "SOFT"\ + }]\ + ]],\ ["phantom-api-monorepo", [\ ["workspace:.", {\ "packageLocation": "./",\ @@ -7469,13 +7469,13 @@ const RAW_RUNTIME_STATE = ["bcrypt", "npm:6.0.0"],\ ["chalk", "npm:4.1.2"],\ ["dotenv", "npm:17.0.1"],\ - ["knip", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:5.61.3"],\ + ["knip", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:5.61.3"],\ ["oxlint", "npm:1.5.0"],\ - ["phantom-api", "workspace:phantom-api"],\ + ["phantom-api-client", "workspace:phantom-api"],\ ["phantom-api-monorepo", "workspace:."],\ ["syncpack", "npm:13.0.4"],\ - ["typedoc", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:0.28.7"],\ - ["typedoc-plugin-markdown", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:4.7.0"],\ + ["typedoc", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:0.28.7"],\ + ["typedoc-plugin-markdown", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:4.7.0"],\ ["typescript", "patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"]\ ],\ "linkType": "SOFT"\ @@ -9367,15 +9367,15 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ - ["virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:0.28.7", {\ - "packageLocation": "./.yarn/__virtual__/typedoc-virtual-9af8bed98b/0/cache/typedoc-npm-0.28.7-01bffbbb89-30c942fa28.zip/node_modules/typedoc/",\ + ["virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:0.28.7", {\ + "packageLocation": "./.yarn/__virtual__/typedoc-virtual-5b61b0313a/0/cache/typedoc-npm-0.28.7-01bffbbb89-30c942fa28.zip/node_modules/typedoc/",\ "packageDependencies": [\ ["@gerrit0/mini-shiki", "npm:3.7.0"],\ ["@types/typescript", null],\ ["lunr", "npm:2.3.9"],\ ["markdown-it", "npm:14.1.0"],\ ["minimatch", "npm:9.0.5"],\ - ["typedoc", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:0.28.7"],\ + ["typedoc", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:0.28.7"],\ ["typescript", "patch:typescript@npm%3A5.8.3#optional!builtin::version=5.8.3&hash=5786d5"],\ ["yaml", "npm:2.8.0"]\ ],\ @@ -9394,12 +9394,12 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ - ["virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:4.7.0", {\ - "packageLocation": "./.yarn/__virtual__/typedoc-plugin-markdown-virtual-67888ea667/0/cache/typedoc-plugin-markdown-npm-4.7.0-cab25d8c3f-066cb8a0f9.zip/node_modules/typedoc-plugin-markdown/",\ + ["virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:4.7.0", {\ + "packageLocation": "./.yarn/__virtual__/typedoc-plugin-markdown-virtual-fe35c66dc1/0/cache/typedoc-plugin-markdown-npm-4.7.0-cab25d8c3f-066cb8a0f9.zip/node_modules/typedoc-plugin-markdown/",\ "packageDependencies": [\ ["@types/typedoc", null],\ - ["typedoc", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:0.28.7"],\ - ["typedoc-plugin-markdown", "virtual:86b7be8dd38592cba87ca3cf1abb5c0da2fddca4c831b45c5226d5764450c4ed3356411563665401336a08f50800bdcaac8524aac051e69b6ab65518e750122f#npm:4.7.0"]\ + ["typedoc", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:0.28.7"],\ + ["typedoc-plugin-markdown", "virtual:896f9be96c54671e2a764d12dd66a3c4ecec90363a4b99a53cdfb2433e3475682e845d14c63ddcdbf06d1acefddd1660a84614f14966ab898a8eeadc4720efae#npm:4.7.0"]\ ],\ "packagePeers": [\ "@types/typedoc",\ @@ -10088,12 +10088,12 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "SOFT"\ }],\ - ["virtual:52c4e47a1af756c3581c016437724dd5a5e123197e605dce921a7b4af2b3533a11fae8e21384c44d753eea716bc74d9d7e456af9c6f0c8febe78a352dae48df9#npm:3.5.2", {\ - "packageLocation": "./.yarn/__virtual__/zod-validation-error-virtual-f05ad98462/0/cache/zod-validation-error-npm-3.5.2-ff101b0599-da50926ec9.zip/node_modules/zod-validation-error/",\ + ["virtual:aa6259b8503d49478c75bdf954304de1eeb552f83b6568d48b0d23d4e117945e0883c37f5f299a20a524c3b7f9d93bf26042037f77783fb50df340aedfd39bf6#npm:3.5.2", {\ + "packageLocation": "./.yarn/__virtual__/zod-validation-error-virtual-202d84f88d/0/cache/zod-validation-error-npm-3.5.2-ff101b0599-da50926ec9.zip/node_modules/zod-validation-error/",\ "packageDependencies": [\ ["@types/zod", null],\ ["zod", "npm:3.25.74"],\ - ["zod-validation-error", "virtual:52c4e47a1af756c3581c016437724dd5a5e123197e605dce921a7b4af2b3533a11fae8e21384c44d753eea716bc74d9d7e456af9c6f0c8febe78a352dae48df9#npm:3.5.2"]\ + ["zod-validation-error", "virtual:aa6259b8503d49478c75bdf954304de1eeb552f83b6568d48b0d23d4e117945e0883c37f5f299a20a524c3b7f9d93bf26042037f77783fb50df340aedfd39bf6#npm:3.5.2"]\ ],\ "packagePeers": [\ "@types/zod",\ diff --git a/package.json b/package.json index ee0c378..1143ce2 100644 --- a/package.json +++ b/package.json @@ -9,7 +9,7 @@ "dotenv": "^17.0.1", "knip": "^5.61.3", "oxlint": "^1.0.0", - "phantom-api": "workspace:*", + "phantom-api-client": "workspace:*", "syncpack": "^13.0.4", "typedoc": "^0.28.7", "typedoc-plugin-markdown": "^4.7.0", diff --git a/phantom-api/package.json b/phantom-api/package.json index cb842e2..8f31fbf 100644 --- a/phantom-api/package.json +++ b/phantom-api/package.json @@ -1,5 +1,5 @@ { - "name": "phantom-api", + "name": "phantom-api-client", "version": "0.2.0-alpha", "bin": { "phantom-migration": "dist/migration-cli.js", diff --git a/yarn.lock b/yarn.lock index 6f3de0c..d6d5672 100644 --- a/yarn.lock +++ b/yarn.lock @@ -6041,42 +6041,42 @@ __metadata: languageName: unknown linkType: soft -"phantom-api-monorepo@workspace:.": +"phantom-api-client@workspace:*, phantom-api-client@workspace:phantom-api": version: 0.0.0-use.local - resolution: "phantom-api-monorepo@workspace:." + resolution: "phantom-api-client@workspace:phantom-api" dependencies: - "@changesets/cli": "npm:^2.29.5" - "@types/bcrypt": "npm:^5.0.2" "@types/node": "npm:^24.0.9" - bcrypt: "npm:^6.0.0" + axios: "npm:^1.10.0" chalk: "npm:^4.1.2" - dotenv: "npm:^17.0.1" + commander: "npm:^12.0.0" knip: "npm:^5.61.3" oxlint: "npm:^1.0.0" - phantom-api: "workspace:*" - syncpack: "npm:^13.0.4" typedoc: "npm:^0.28.7" typedoc-plugin-markdown: "npm:^4.7.0" typescript: "npm:^5.8.3" + bin: + phantom-migration: dist/migration-cli.js + phantom-seed: dist/seed-cli.js languageName: unknown linkType: soft -"phantom-api@workspace:*, phantom-api@workspace:phantom-api": +"phantom-api-monorepo@workspace:.": version: 0.0.0-use.local - resolution: "phantom-api@workspace:phantom-api" + resolution: "phantom-api-monorepo@workspace:." dependencies: + "@changesets/cli": "npm:^2.29.5" + "@types/bcrypt": "npm:^5.0.2" "@types/node": "npm:^24.0.9" - axios: "npm:^1.10.0" + bcrypt: "npm:^6.0.0" chalk: "npm:^4.1.2" - commander: "npm:^12.0.0" + dotenv: "npm:^17.0.1" knip: "npm:^5.61.3" oxlint: "npm:^1.0.0" + phantom-api-client: "workspace:*" + syncpack: "npm:^13.0.4" typedoc: "npm:^0.28.7" typedoc-plugin-markdown: "npm:^4.7.0" typescript: "npm:^5.8.3" - bin: - phantom-migration: dist/migration-cli.js - phantom-seed: dist/seed-cli.js languageName: unknown linkType: soft From afbfde089b04570624c961965133c4f5d798dc79 Mon Sep 17 00:00:00 2001 From: salnika Date: Sun, 10 Aug 2025 00:20:11 +0200 Subject: [PATCH 4/7] chore: fix dockerfile --- Dockerfile | 11 +- phantom-api/README.md | 292 +++++++++++++++++++++--------------------- 2 files changed, 155 insertions(+), 148 deletions(-) diff --git a/Dockerfile b/Dockerfile index cff1eb4..8c01aa1 100644 --- a/Dockerfile +++ b/Dockerfile @@ -77,9 +77,13 @@ COPY --from=builder --chown=phantom:phantom /app/package.json ./package.json RUN mkdir -p /app/data /app/logs && \ chown -R phantom:phantom /app/data /app/logs -# Install production dependencies (en root pour éviter les problèmes de permissions) -WORKDIR /app/phantom-api-backend -RUN npm install --production --omit=dev +# Enable corepack for yarn support +RUN corepack enable + +# Install production dependencies using yarn (en root pour éviter les problèmes de permissions) +WORKDIR /app +ENV NODE_OPTIONS="--experimental-loader=/app/.pnp.loader.mjs" +RUN yarn install --immutable --production # Change ownership après installation RUN chown -R phantom:phantom /app @@ -91,4 +95,5 @@ EXPOSE 3000 HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \ CMD curl -f http://localhost:3000/health || exit 1 +ENV NODE_OPTIONS="--experimental-loader=/app/.pnp.loader.mjs" CMD ["node", "dist/index.js"] diff --git a/phantom-api/README.md b/phantom-api/README.md index eafb8ec..fef9f10 100644 --- a/phantom-api/README.md +++ b/phantom-api/README.md @@ -1,39 +1,42 @@
- Phantom API Logo + Phantom API Logo # Phantom API Client - - **Dynamic backend system that builds type-safe, schema-based APIs with zero boilerplate** - + + **The official TypeScript/JavaScript client for Phantom API - Create powerful backends without the complexity.** + [![npm version](https://img.shields.io/npm/v/phantom-api-client.svg)](https://www.npmjs.com/package/phantom-api-client) [![npm downloads](https://img.shields.io/npm/dm/phantom-api-client.svg)](https://www.npmjs.com/package/phantom-api-client) [![GitHub stars](https://img.shields.io/github/stars/salnika/phantom-api.dev.svg)](https://github.com/salnika/phantom-api.dev) - [![License: CC BY-NC-SA 4.0](https://img.shields.io/badge/License-CC%20BY--NC--SA%204.0-blue.svg)](https://creativecommons.org/licenses/by-nc-sa/4.0/) - [![Documentation](https://img.shields.io/badge/docs-phantom--api.dev-blue)](https://phantom-api.dev) + [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) + [![TypeScript Ready](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/)
## TL;DR -**Phantom API is a dynamic backend system that builds type-safe, schema-based APIs with zero boilerplate.** +**It creates your backend by calling it** 🪄 -Skip writing database schemas, migrations, validation rules, and REST endpoints. Just call your API and watch it build itself in real-time. +No need to write schemas, migrations, or endpoints. Just call your API and watch it build itself in real-time! ## Quick Example ```typescript import { createClient } from 'phantom-api-client'; -const client = createClient({ baseURL: 'https://api.example.com' }); -const tasks = client.resource('Task'); +const client = createClient(); +client.setEndpoint('https://your-phantom-api.com'); -// 🎯 This single call creates the database table, validation schema, and REST endpoints -await tasks.create({ name: 'Write README', done: false, priority: 'high' }); +const users = client.resource('users'); -// ✅ Table "tasks" now exists with columns: id, name, done, priority, created_at -const list = await tasks.read({ where: { done: false } }); -``` +// 🎯 This single call creates the entire backend infrastructure +await users.create({ + name: 'John Doe', + email: 'john@example.com' +}); -[→ See complete examples](https://phantom-api.dev/docs/examples) +// ✨ Database table, validation rules, and REST endpoints are now live! +const allUsers = await users.getAll(); +``` ## Installation @@ -45,193 +48,192 @@ yarn add phantom-api-client bun add phantom-api-client ``` -## Documentation +## ✨ Features -📚 **[Full documentation →](https://phantom-api.dev)** +- 🪄 **Magic Backend Creation**: Your backend builds itself as you call it - no setup required! +- 🚀 **Zero Boilerplate**: Skip the boring stuff, just start building features +- 🔐 **Authentication Ready**: JWT tokens and sessions work out of the box +- 📊 **Type Safety**: TypeScript loves it, and so will you +- 🎯 **Smart Queries**: Filter, sort, paginate like you're reading your mind +- ⚡ **Lightning Fast**: Optimized for speed, built for scale +- 🛠️ **CLI Superpowers**: Migrations and seeds that actually make sense +- 💝 **Developer Joy**: Because coding should be fun, not frustrating -## Why Phantom API? +## 🚀 Quick Start -🧠 **Data-first**: Auto-generates tables, validations, and routes from your actual data -🔐 **Fine-grained permissions**: Built-in policy system with role-based and attribute-based access control -⚡️ **Fast to deploy**: No backend code required - works with any frontend framework -🧱 **Works everywhere**: Next.js, React Native, Vue, Svelte, vanilla JavaScript -🎯 **Type-safe**: Full TypeScript support with auto-generated types -🔄 **Real-time**: Built-in WebSocket support for live data updates +### Basic Usage -## Feature Comparison +```typescript +import { createClient } from 'phantom-api-client'; + +// Initialize the client (yes, it's this simple) +const client = createClient(); +client.setEndpoint('https://your-phantom-api.com'); -| Tool | Backend Code Needed | Permissions | Hosted | Custom Logic | -|------|-------------------|-------------|---------|--------------| -| **Phantom** | ❌ None | ✅ Built-in | ✅ | ✅ With Hooks | -| Supabase | ✅ SQL/Edge Functions | ⚠️ Limited | ✅ | ✅ | -| Strapi | ✅ JS/TS | ✅ Advanced | ❌ | ✅ | -| Hasura | ❌ GraphQL Config | ⚠️ Complex | ✅ | ⚠️ Indirect | -| Firebase | ✅ Cloud Functions | ⚠️ Basic Rules | ✅ | ⚠️ Limited | +// Grab a resource (it doesn't exist yet, but it will!) +const users = client.resource('users'); -## Core Features +// Create a user (and boom! 💥 The entire backend comes to life) +await users.create({ + name: 'John Doe', + email: 'john@example.com' +}); -### 🚀 Dynamic Resource Creation +// Now you can do all the usual stuff +const allUsers = await users.getAll(); +const user = await users.get(1); +await users.update(1, { name: 'Jane Doe' }); +await users.delete(1); +``` + +### Advanced Usage (aka the cool stuff 😎) ```typescript -// Creates table, schema, and endpoints automatically -const users = client.resource('User'); -const posts = client.resource('Post'); -const comments = client.resource('Comment'); - -// Relationships detected from field names -await posts.create({ - title: 'Hello World', - content: 'My first post!', - authorId: 'user_123' // 👈 Auto-creates foreign key to User table +// Query like a pro +const activeUsers = await users.getAll({ + filters: { status: 'active' }, + sort: 'created_at:desc', + limit: 10, + offset: 0 +}); + +// Relationships? We got you covered +const posts = client.resource('posts'); +const userPosts = await posts.getAll({ + filters: { user_id: 1 } }); + +// Batch operations because why not? +await users.createMany([ + { name: 'User 1', email: 'user1@example.com' }, + { name: 'User 2', email: 'user2@example.com' } +]); ``` -### 🔍 Advanced Querying +### Authentication (secure by default 🔒) ```typescript -const posts = await client.resource('Post').read({ - where: { - published: true, - createdAt: { gte: '2024-01-01' }, - tags: { contains: 'javascript' } - }, - populate: ['author', 'comments'], - sort: ['-createdAt'], - limit: 20 +// Just plug in your token +client.setAuth('your-jwt-token'); + +// Or do it all at once +const client = createClient({ + endpoint: 'https://your-phantom-api.com', + token: 'your-jwt-token' }); ``` -### ⚡ Batch Operations +## 🛠️ CLI Tools (for when you want to feel like a wizard 🧙‍♂️) -```typescript -const results = await client.batch([ - { resource: 'User', action: 'create', data: { name: 'Alice' } }, - { resource: 'User', action: 'create', data: { name: 'Bob' } }, - { resource: 'Post', action: 'create', data: { title: 'Hello', authorId: 'user_123' } } -]); +### Migration CLI + +```bash +# Generate a new migration +phantom-migration generate create_users_table + +# Run migrations +phantom-migration up + +# Rollback migrations +phantom-migration down ``` -### 🎯 Type Safety +### Seed CLI + +```bash +# Create seed data +phantom-seed create users + +# Run seeds +phantom-seed run +``` + +## 📖 API Reference + +### Client Methods + +- `createClient(options?)` - Create a new Phantom API client +- `setEndpoint(url)` - Set the API endpoint URL +- `resource(name)` - Get a resource instance +- `setAuth(token)` - Set authentication token + +### Resource Methods + +- `getAll(options?)` - Fetch all records +- `get(id)` - Fetch single record by ID +- `create(data)` - Create new record +- `createMany(data[])` - Create multiple records +- `update(id, data)` - Update existing record +- `delete(id)` - Delete record +- `count(filters?)` - Count records + +### Query Options ```typescript -interface User { - id: string; - email: string; - name: string; - createdAt: Date; +interface QueryOptions { + filters?: Record; + sort?: string; + limit?: number; + offset?: number; + include?: string[]; } - -const user = await client.resource('User').create({ - email: 'john@example.com', - name: 'John Doe' -}); -// user is fully typed! ✅ ``` -## Real-World Usage +## Real-World Examples ### E-commerce Store ```typescript -// Product catalog with categories and inventory -await client.resource('Product').create({ +// Product catalog with categories +await client.resource('products').create({ name: 'iPhone 15 Pro', price: 999.99, - categoryId: 'electronics', - inStock: true, - variants: ['128GB', '256GB', '512GB'] -}); -``` - -### Social Media App -```typescript -// User posts with likes and comments -await client.resource('Post').create({ - content: 'Building with Phantom API! 🚀', - authorId: 'user_123', - tags: ['#phantomapi', '#nocode'] -}); - -await client.resource('Like').create({ - postId: 'post_456', - userId: 'user_789' + category_id: 'electronics', + in_stock: true }); ``` ### Task Management ```typescript // Project tasks with assignments -await client.resource('Task').create({ +await client.resource('tasks').create({ title: 'Design new homepage', - description: 'Create wireframes and mockups', - assigneeId: 'user_456', - projectId: 'proj_123', + assignee_id: 'user_456', + project_id: 'proj_123', status: 'in_progress', - priority: 'high', - dueDate: '2024-02-15' + priority: 'high' }); ``` -## Authentication & Security +## Environment Management -```typescript -// JWT authentication -const client = createClient({ - baseURL: 'https://api.yourapp.com', - token: 'your-jwt-token' -}); -``` - -## Migration & Deployment - -### CLI Tools -```bash -# Preview database changes -phantom-migration --preview - -# Apply migrations -phantom-migration --apply - -# Seed development data -phantom-seed --file ./seeds/demo.json -``` - -### Environment Management ```typescript const devClient = createClient({ - baseURL: 'http://localhost:3000' + endpoint: 'http://localhost:3000' }); const prodClient = createClient({ - baseURL: 'https://api.yourapp.com', + endpoint: 'https://api.yourapp.com', token: process.env.PHANTOM_API_TOKEN }); ``` -## Roadmap / Contributing +## 🤝 Contributing -We're actively developing Phantom API! Here's what's coming: +We welcome contributions! Please see our [Contributing Guide](../CONTRIBUTING.md) for details. -- 🔄 Real-time subscriptions -- 📊 Advanced analytics dashboard -- 🤖 AI-powered schema suggestions -- 📱 Mobile SDKs (React Native, Flutter) +## 📄 License -**Want to contribute?** Check out our [GitHub Issues](https://github.com/salnika/phantom-api.dev/issues) or join our community! +Licensed under the [MIT License](LICENSE). -## Community & Support +## 🆘 Support -- 📖 **Documentation**: [phantom-api.dev](https://phantom-api.dev) -- 💬 **Discord**: [Join our community](https://discord.gg/phantom-api) -- 🐛 **Issues**: [GitHub Issues](https://github.com/salnika/phantom-api.dev/issues) -- 🔄 **Updates**: Follow [@PhantomAPI](https://twitter.com/phantomapi) on Twitter - -## License - -CC BY-NC-SA 4.0 – see the LICENSE file in the repository root. +- 📖 [Documentation](https://github.com/salnika/phantom-api.dev) +- 🐛 [Issue Tracker](https://github.com/salnika/phantom-api.dev/issues) +- 💬 [Discussions](https://github.com/salnika/phantom-api.dev/discussions) ---
Built with ❤️ by the Phantom API team
- Stop writing boilerplate. Start building features. -
+ Connect to powerful backends without the complexity. + \ No newline at end of file From fd622713793df326d3e13c9aa24adeffb34322c4 Mon Sep 17 00:00:00 2001 From: salnika Date: Sun, 10 Aug 2025 00:29:43 +0200 Subject: [PATCH 5/7] chore: fix dockerfile --- Dockerfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Dockerfile b/Dockerfile index 8c01aa1..3e285ca 100644 --- a/Dockerfile +++ b/Dockerfile @@ -83,7 +83,7 @@ RUN corepack enable # Install production dependencies using yarn (en root pour éviter les problèmes de permissions) WORKDIR /app ENV NODE_OPTIONS="--experimental-loader=/app/.pnp.loader.mjs" -RUN yarn install --immutable --production +RUN yarn workspaces focus phantom-api-backend --production # Change ownership après installation RUN chown -R phantom:phantom /app From d1f7dd539d5de38e82e667f20297c179715de3f0 Mon Sep 17 00:00:00 2001 From: alexis-salnikoff-wmx Date: Thu, 14 Aug 2025 16:20:44 +0200 Subject: [PATCH 6/7] chore: update Readme --- README.md | 24 ++- phantom-api/README.md | 421 ++++++++++++++++++++++++++---------------- 2 files changed, 277 insertions(+), 168 deletions(-) diff --git a/README.md b/README.md index 90c9f38..c770bc4 100644 --- a/README.md +++ b/README.md @@ -2,22 +2,26 @@ Phantom API Logo -

- CI Status - Latest Release - License - Node.js Version - Yarn - npm version - Docker image version -

+ + + + + + + + + + +
Latest Releasenpm versionDocker image version
DockerLicense
# Phantom API - Self-Generating Backend A dynamic backend system that automatically creates API endpoints, database tables, and validation schemas based on api call from frontend. -[Complete Documentation](https://salnika.github.io/phantom-api.dev/) +- [Website](https://phantom-api.dev) +- [github](https://github.com/Salnika/phantom-api.dev) +- [Complete Documentation](https://salnika.github.io/phantom-api.dev/) ## Features diff --git a/phantom-api/README.md b/phantom-api/README.md index fef9f10..8aafb7e 100644 --- a/phantom-api/README.md +++ b/phantom-api/README.md @@ -9,231 +9,336 @@ [![npm downloads](https://img.shields.io/npm/dm/phantom-api-client.svg)](https://www.npmjs.com/package/phantom-api-client) [![GitHub stars](https://img.shields.io/github/stars/salnika/phantom-api.dev.svg)](https://github.com/salnika/phantom-api.dev) [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) - [![TypeScript Ready](https://img.shields.io/badge/TypeScript-Ready-blue.svg)](https://www.typescriptlang.org/) -## TL;DR +# Phantom API - Self-Generating Backend -**It creates your backend by calling it** 🪄 +A dynamic backend system that automatically creates API endpoints, database tables, and validation schemas based on api call from frontend. -No need to write schemas, migrations, or endpoints. Just call your API and watch it build itself in real-time! +- [Website](https://phantom-api.dev) +- [github](https://github.com/Salnika/phantom-api.dev) +- [Complete Documentation](https://salnika.github.io/phantom-api.dev/) -## Quick Example +## Features -```typescript -import { createClient } from 'phantom-api-client'; +- **Dynamic API**: Single route `/api/:resource/:action` handles all operations +- **Dynamic Table Creation**: Tables automatically created from API calls, no configuration needed +- **Advanced Relations**: Foreign keys, cascading deletes, self-referencing tables +- **Rich Field Types**: String, text, integer, boolean, datetime, enum, JSON, email +- **Zod Validation**: Automatic schema generation and validation +- **🆕 Advanced Policies Management**: Role-based, attribute-based, and custom access control policies +- **JWT Security**: Secure authentication with configurable roles and permissions +- **Admin Interface**: Modern React-based admin panel with policy management and logs viewer +- **Client Package**: TypeScript NPM package for frontend integration +- **Process Management**: PM2 ecosystem for production deployment +- **Structured Logging**: Pino logger with file rotation and admin interface +- **Docker Ready**: Containerized backend with persistent SQLite storage -const client = createClient(); -client.setEndpoint('https://your-phantom-api.com'); +## Project Structure -const users = client.resource('users'); +``` +├── phantom-api-backend/ # backend (Express server with dynamic API) +│ ├── src/ # TypeScript source code +│ ├── meta/ # Optional schema files (auto-generated) +│ ├── logs/ # Application and error logs +│ └── data/ # SQLite database files +├── admin-interface/ # admin (React admin panel) +├── phantom-api/ # client (NPM package for frontend integration) +├── ecosystem.config.js # PM2 process configuration +├── Dockerfile # Backend containerization +└── docker-compose.yml # Multi-service orchestration +``` -// 🎯 This single call creates the entire backend infrastructure -await users.create({ - name: 'John Doe', - email: 'john@example.com' -}); +## Prerequisites -// ✨ Database table, validation rules, and REST endpoints are now live! -const allUsers = await users.getAll(); -``` +Before getting started, ensure you have the following installed: + +### Required +- **Node.js** 18+ (recommended: 22+) +- **Yarn** 4.9.2 (package manager) +- **Git** (version control) -## Installation +### Optional (for full development experience) +- **PM2** (process management): `yarn add -g pm2` +- **Python 3.8+** and **MkDocs** (documentation): `pip install mkdocs mkdocs-material` +- **Docker** and **Docker Compose** (containerization) +### Installation Verification ```bash -npm install phantom-api-client -# or -yarn add phantom-api-client -# or -bun add phantom-api-client +# Check versions +node --version # Should be 18+ +yarn --version # Should be 4.9.2 +git --version # Any recent version + +# Optional tools +pm2 --version # For process management +mkdocs --version # For documentation server +docker --version # For containerized deployment ``` -## ✨ Features - -- 🪄 **Magic Backend Creation**: Your backend builds itself as you call it - no setup required! -- 🚀 **Zero Boilerplate**: Skip the boring stuff, just start building features -- 🔐 **Authentication Ready**: JWT tokens and sessions work out of the box -- 📊 **Type Safety**: TypeScript loves it, and so will you -- 🎯 **Smart Queries**: Filter, sort, paginate like you're reading your mind -- ⚡ **Lightning Fast**: Optimized for speed, built for scale -- 🛠️ **CLI Superpowers**: Migrations and seeds that actually make sense -- 💝 **Developer Joy**: Because coding should be fun, not frustrating +## Quick Start -## 🚀 Quick Start +### 1. Install Dependencies +```bash +yarn install +``` -### Basic Usage +### 2. Environment Setup +Copy the example environment file and configure it: +```bash +cp .env.example .env +``` -```typescript -import { createClient } from 'phantom-api-client'; +Edit `.env` with your configuration: +```env +# Server Configuration +PORT=3000 +NODE_ENV=development -// Initialize the client (yes, it's this simple) -const client = createClient(); -client.setEndpoint('https://your-phantom-api.com'); +# JWT Secret Key (CHANGE THIS IN PRODUCTION!) +JWT_SECRET=your-super-secret-jwt-key-change-this-in-production -// Grab a resource (it doesn't exist yet, but it will!) -const users = client.resource('users'); +# Database Configuration +DB_PATH=./data/phantom.db -// Create a user (and boom! 💥 The entire backend comes to life) -await users.create({ - name: 'John Doe', - email: 'john@example.com' -}); - -// Now you can do all the usual stuff -const allUsers = await users.getAll(); -const user = await users.get(1); -await users.update(1, { name: 'Jane Doe' }); -await users.delete(1); +# Admin Panel Configuration +ADMIN_EMAIL=admin@phantom-api.com +ADMIN_PASSWORD=admin123 ``` -### Advanced Usage (aka the cool stuff 😎) +### 3. Start All Services with PM2 +```bash +# Install PM2 globally (if not already installed) +yarn add -g pm2 -```typescript -// Query like a pro -const activeUsers = await users.getAll({ - filters: { status: 'active' }, - sort: 'created_at:desc', - limit: 10, - offset: 0 -}); +# Start all services +yarn pm2:start -// Relationships? We got you covered -const posts = client.resource('posts'); -const userPosts = await posts.getAll({ - filters: { user_id: 1 } -}); +# Check status +pm2 status -// Batch operations because why not? -await users.createMany([ - { name: 'User 1', email: 'user1@example.com' }, - { name: 'User 2', email: 'user2@example.com' } -]); +# View logs +yarn pm2:logs ``` -### Authentication (secure by default 🔒) +Services will run on: +- **Backend**: http://localhost:3000 - API endpoints and data management +- **Admin Interface**: http://localhost:5173 - Modern admin panel with logs viewer +- **# Demo Frontend**: http://localhost:5174 - Example application using the API +- **Website**: http://localhost:5175 - Marketing and documentation site +- **Documentation**: http://localhost:8000 - MkDocs technical documentation -```typescript -// Just plug in your token -client.setAuth('your-jwt-token'); +### 4. Alternative: Start Individual Services +```bash +# Backend only +cd phantom-api-backend && yarn dev -// Or do it all at once -const client = createClient({ - endpoint: 'https://your-phantom-api.com', - token: 'your-jwt-token' -}); +# Admin interface only +cd admin-interface && yarn dev + +# Demo frontend only +cd demo && yarn dev + +# Documentation server only +cd public-doc && mkdocs serve ``` -## 🛠️ CLI Tools (for when you want to feel like a wizard 🧙‍♂️) +### 5. Use Client Package +```typescript +import { setEndpoint, setToken, resource } from 'phantom-api'; -### Migration CLI +// Configure +setEndpoint('http://localhost:3000'); +setToken('your-jwt-token'); // optional -```bash -# Generate a new migration -phantom-migration generate create_users_table +// Use resources +const users = resource('User'); +await users.create({ email: 'test@example.com', name: 'John' }); +const allUsers = await users.read(); -# Run migrations -phantom-migration up +// Update a user +await users.update({ id: allUsers[0].id, name: 'John Doe Updated' }); -# Rollback migrations -phantom-migration down +// Delete a user +await users.delete({ id: allUsers[0].id }); ``` -### Seed CLI +## Docker Deployment + +For containerized deployment with optimized production setup: ```bash -# Create seed data -phantom-seed create users +# Copy environment template +cp .env.example .env + +# Generate secure JWT secret (32+ characters) +openssl rand -base64 32 +# Copy to JWT_SECRET in .env + +# Build and start +docker-compose up --build -d -# Run seeds -phantom-seed run +# Verify deployment +curl http://localhost:3000/health ``` -## 📖 API Reference +**Services accessible at:** +- Backend API: http://localhost:3000 +- Admin Interface: http://localhost:3000/admin +- Health Check: http://localhost:3000/health -### Client Methods +For detailed Docker configuration, see documentation at http://localhost:8000 (when MkDocs is running). -- `createClient(options?)` - Create a new Phantom API client -- `setEndpoint(url)` - Set the API endpoint URL -- `resource(name)` - Get a resource instance -- `setAuth(token)` - Set authentication token +## Dynamic Table Creation -### Resource Methods +Phantom API creates database tables automatically from your API calls - no configuration files needed! -- `getAll(options?)` - Fetch all records -- `get(id)` - Fetch single record by ID -- `create(data)` - Create new record -- `createMany(data[])` - Create multiple records -- `update(id, data)` - Update existing record -- `delete(id)` - Delete record -- `count(filters?)` - Count records +### How It Works -### Query Options +1. **Call Any Resource**: Simply use `resource('AnyTableName')` in your frontend +2. **Auto-Detection**: The system detects field types from the data you send +3. **Table Creation**: SQLite tables are created instantly with appropriate columns +4. **Schema Evolution**: New fields are automatically added when you send new data + +### Field Type Detection ```typescript -interface QueryOptions { - filters?: Record; - sort?: string; - limit?: number; - offset?: number; - include?: string[]; -} +// These calls automatically create a User table +const User = resource('User'); +User.create({ + email: 'user@example.com', // → VARCHAR (email format detected) + name: 'John Doe', // → VARCHAR + age: 30, // → INTEGER + isActive: true, // → BOOLEAN + birthDate: '1990-01-01', // → DATE + createdAt: new Date(), // → DATETIME + metadata: { role: 'admin' } // → JSON +}); ``` -## Real-World Examples +### Automatic Relations -### E-commerce Store ```typescript -// Product catalog with categories -await client.resource('products').create({ - name: 'iPhone 15 Pro', - price: 999.99, - category_id: 'electronics', - in_stock: true +// Foreign key relationships are auto-detected +const Article = resource('Article'); +Article.create({ + title: 'My Article', + content: 'Article content...', + authorId: 'user_123', // → Creates FK to User table + categoryId: 'cat_456' // → Creates FK to Category table }); ``` -### Task Management -```typescript -// Project tasks with assignments -await client.resource('tasks').create({ - title: 'Design new homepage', - assignee_id: 'user_456', - project_id: 'proj_123', - status: 'in_progress', - priority: 'high' -}); +### Supported Data Types + +- **String**: Text fields, emails, URLs +- **Integer**: Numbers, IDs, counts +- **Boolean**: true/false values +- **Date**: ISO date strings +- **DateTime**: ISO datetime strings +- **JSON**: Objects and arrays +- **Relations**: Foreign keys (detected by 'Id' suffix) + +## API Usage + +All operations use POST requests to `/api/:resource/:action`: + +### Create +```bash +curl -X POST http://localhost:3000/api/User/create \ + -H "Content-Type: application/json" \ + -d '{"email": "user@example.com", "name": "John Doe"}' ``` -## Environment Management +### Read +```bash +# Get all +curl -X POST http://localhost:3000/api/User/read \ + -H "Content-Type: application/json" \ + -d '{}' + +# Get by ID +curl -X POST http://localhost:3000/api/User/read \ + -H "Content-Type: application/json" \ + -d '{"id": "user_123"}' +``` -```typescript -const devClient = createClient({ - endpoint: 'http://localhost:3000' -}); +### Update +```bash +curl -X POST http://localhost:3000/api/User/update \ + -H "Content-Type: application/json" \ + -d '{"id": "user_123", "name": "Jane Doe"}' +``` -const prodClient = createClient({ - endpoint: 'https://api.yourapp.com', - token: process.env.PHANTOM_API_TOKEN -}); +### Delete +```bash +curl -X POST http://localhost:3000/api/User/delete \ + -H "Content-Type: application/json" \ + -d '{"id": "user_123"}' ``` -## 🤝 Contributing +## Authentication & Authorization + +### JWT Authentication +Generate JWT tokens in the admin interface with configurable roles: +- `anon`: Anonymous access (limited) +- `user`: Standard user permissions +- `admin`: Administrative access +- `moderator`: Content moderation permissions +- `viewer`: Read-only access +- `editor`: Content editing permissions + +### Advanced Policies System +Phantom API now includes a comprehensive policies management system: + +- **Role-Based Access Control (RBAC)**: Traditional role-based permissions +- **Attribute-Based Access Control (ABAC)**: Dynamic permissions based on user/resource attributes +- **Custom Policies**: Complex business logic with conditional rules +- **Policy Templates**: Pre-built policies for common scenarios +- **Real-time Testing**: Test policies before deployment +- **Analytics & Monitoring**: Track policy usage and access patterns + +**Example Policy:** +```json +{ + "name": "User Data Ownership", + "type": "ATTRIBUTE_BASED", + "rules": [ + { + "resource": "User", + "action": "update", + "effect": "ALLOW", + "conditions": [ + { + "field": "user.id", + "operator": "eq", + "value": "${resource.id}", + "context": "user" + } + ] + } + ] +} +``` -We welcome contributions! Please see our [Contributing Guide](../CONTRIBUTING.md) for details. +**Security Note**: Make sure to change the default JWT_SECRET in production! -## 📄 License +📖 **[Complete Policies Documentation](./POLICIES_DOCUMENTATION.md)** -Licensed under the [MIT License](LICENSE). +## How It Works -## 🆘 Support +1. **Frontend Call**: `resource('User').create({ email: 'test@mail.com', name: 'MARTIN' })` +2. **Auto-Detection**: System analyzes data types and structure +3. **Table Creation**: SQLite table created instantly if it doesn't exist +4. **Schema Evolution**: New columns added automatically for new fields +5. **Response**: Data saved and returned with generated ID -- 📖 [Documentation](https://github.com/salnika/phantom-api.dev) -- 🐛 [Issue Tracker](https://github.com/salnika/phantom-api.dev/issues) -- 💬 [Discussions](https://github.com/salnika/phantom-api.dev/discussions) +The system learns from your data and automatically: +- Creates tables with appropriate column types +- Detects relationships from field names (e.g., 'authorId' → User table) +- Generates validation schemas on-the-fly +- Provides admin interface for data management ---- +**Zero configuration required** - just start coding and let Phantom API handle the database! -
- Built with ❤️ by the Phantom API team
- Connect to powerful backends without the complexity. -
\ No newline at end of file +Perfect for rapid prototyping and dynamic applications! From d3e95edc6fc01983d0e5d7b8a008b6fa7b1c12ff Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 16 Sep 2025 09:06:41 +0000 Subject: [PATCH 7/7] chore(ci): bump tj-actions/changed-files from 44 to 47 Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44 to 47. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/v44...v47) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-version: '47' dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- .github/workflows/dispatch.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dispatch.yml b/.github/workflows/dispatch.yml index 52280d5..39e7696 100644 --- a/.github/workflows/dispatch.yml +++ b/.github/workflows/dispatch.yml @@ -34,7 +34,7 @@ jobs: - name: Get changed files id: changed-files - uses: tj-actions/changed-files@v44 + uses: tj-actions/changed-files@v47 - name: Generate Matrix from changed Workspaces id: generate-matrix