From adad0b98bd9cb0bacef10a19f57a664103746eec Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 29 May 2026 17:15:23 +0000 Subject: [PATCH 1/5] chore: bump dev version to 1.1.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c093dfb..0a970f6 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "astro-scaffold", "type": "module", - "version": "0.0.1", + "version": "1.1.0", "engines": { "node": ">=22.12.0" }, From 9ebe104ad45d64dad2c17422e02ae3c8e4f89b35 Mon Sep 17 00:00:00 2001 From: Fajrian Aidil Pratama Date: Sat, 30 May 2026 01:29:48 +0800 Subject: [PATCH 2/5] ci: drop pnpm version pin (reads packageManager) + add housekeeping job --- .github/workflows/deploy.yml | 2 -- .github/workflows/housekeeping.yml | 12 ++++++++++++ 2 files changed, 12 insertions(+), 2 deletions(-) create mode 100644 .github/workflows/housekeeping.yml diff --git a/.github/workflows/deploy.yml b/.github/workflows/deploy.yml index 292714f..7d98452 100644 --- a/.github/workflows/deploy.yml +++ b/.github/workflows/deploy.yml @@ -40,8 +40,6 @@ jobs: echo "Deploying v$VERSION" - uses: pnpm/action-setup@v4 - with: - version: 10 - uses: actions/setup-node@v4 with: diff --git a/.github/workflows/housekeeping.yml b/.github/workflows/housekeeping.yml new file mode 100644 index 0000000..3b18a56 --- /dev/null +++ b/.github/workflows/housekeeping.yml @@ -0,0 +1,12 @@ +name: Housekeeping + +on: + pull_request: + types: [closed] + +jobs: + housekeeping: + name: Housekeeping + uses: banua-coder/banua-coder-workflow/.github/workflows/housekeeping.yml@main + with: + protected-branches: 'main,develop' From b82b68aa7321ed5f0773516897ac9b9dc6976e69 Mon Sep 17 00:00:00 2001 From: Fajrian Aidil Pratama Date: Sat, 30 May 2026 01:32:44 +0800 Subject: [PATCH 3/5] fix(ci): add sharp as explicit dependency so Linux image binaries install --- package.json | 1 + pnpm-lock.yaml | 106 +++++++------------------------------------------ 2 files changed, 16 insertions(+), 91 deletions(-) diff --git a/package.json b/package.json index 0a970f6..540f136 100644 --- a/package.json +++ b/package.json @@ -24,6 +24,7 @@ "gsap": "^3.15.0", "lenis": "^1.3.23", "lucide-astro": "^0.556.0", + "sharp": "^0.34.5", "tailwindcss": "^4.2.4", "zod": "^4.4.3" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 1540b98..a884034 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -44,6 +44,9 @@ importers: lucide-astro: specifier: ^0.556.0 version: 0.556.0(astro@6.3.1(@types/node@24.12.3)(jiti@2.7.0)(lightningcss@1.32.0)(rollup@4.60.3)(yaml@2.8.4)) + sharp: + specifier: ^0.34.5 + version: 0.34.5 tailwindcss: specifier: ^4.2.4 version: 4.2.4 @@ -969,9 +972,6 @@ packages: '@types/unist@3.0.3': resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==} - '@types/yauzl@2.10.3': - resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} - '@ungap/structured-clone@1.3.1': resolution: {integrity: sha512-mUFwbeTqrVgDQxFveS+df2yfap6iuP20NAKAsBt5jDEoOTDew+zwLAOilHCeQJOVSvmgCX4ogqIrA0mnyr08yQ==} @@ -1011,6 +1011,10 @@ packages: engines: {node: '>=0.4.0'} hasBin: true + adm-zip@0.5.17: + resolution: {integrity: sha512-+Ut8d9LLqwEvHHJl1+PIHqoyDxFgVN847JTVM3Izi3xHDWPE4UtzzXysMZQs64DMcrJfBeS/uoEP4AD3HQHnQQ==} + engines: {node: '>=12.0'} + agent-base@9.0.0: resolution: {integrity: sha512-TQf59BsZnytt8GdJKLPfUZ54g/iaUL2OWDSFCCvMOhsHduDQxO8xC4PNeyIkVcA5KwL2phPSv0douC0fgWzmnA==} engines: {node: '>= 20'} @@ -1098,9 +1102,6 @@ packages: boolbase@1.0.0: resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==} - buffer-crc32@0.2.13: - resolution: {integrity: sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==} - call-bind-apply-helpers@1.0.2: resolution: {integrity: sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==} engines: {node: '>= 0.4'} @@ -1131,8 +1132,8 @@ packages: resolution: {integrity: sha512-TQMmc3w+5AxjpL8iIiwebF73dRDF4fBIieAqGn9RGCWaEVwQ6Fb2cGe31Yns0RRIzii5goJ1Y7xbMwo1TxMplw==} engines: {node: '>= 20.19.0'} - chromedriver@148.0.2: - resolution: {integrity: sha512-9N9J6XxkB7dub7dcYzJomNfTbaEQA5qILpdha5cxUxgDC2hwE3u8yV/7tkJacSSfPGCHKHp05NYmAitQ4Y7tSw==} + chromedriver@149.0.0: + resolution: {integrity: sha512-kFZI2Tft4p6QXGhtbjohRHad2uGhwcH95YH2CLVhOjQM676+QnJPl00OgcB1o3tTobmW8BezufMYTKYFjmTvtg==} engines: {node: '>=22'} hasBin: true @@ -1337,9 +1338,6 @@ packages: emoji-regex@8.0.0: resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==} - end-of-stream@1.4.5: - resolution: {integrity: sha512-ooEGc6HP26xXq/N+GCGOT0JKCLDGrq2bQUZrQ7gyrJiZANJ/8YDTxTpQBXGMn+WbIQXNVpyWymm7KYVICQnyOg==} - enhanced-resolve@5.21.1: resolution: {integrity: sha512-8p7DUVq6XJnZEz9W4oSwiwycxBIjHjRzYb3Je3zVN+geKTRQKzAkR/K4PBExlS0090d9nshak6phMUxr3PDjmQ==} engines: {node: '>=10.13.0'} @@ -1445,11 +1443,6 @@ packages: extend@3.0.2: resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} - extract-zip@2.0.1: - resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} - engines: {node: '>= 10.17.0'} - hasBin: true - fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} @@ -1472,9 +1465,6 @@ packages: resolution: {integrity: sha512-C0AaNuC+mscy6vrAQKAc/rMq+zAPHodfHGZu4sGVehvAQt/JLG1O5zEcYcXSY5zSqr4YVgxsB+pHXTq0i7eDlg==} hasBin: true - fd-slicer@1.1.0: - resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} - fdir@6.5.0: resolution: {integrity: sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==} engines: {node: '>=12.0.0'} @@ -1531,10 +1521,6 @@ packages: resolution: {integrity: sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==} engines: {node: '>= 0.4'} - get-stream@5.2.0: - resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} - engines: {node: '>=8'} - get-tsconfig@5.0.0-beta.4: resolution: {integrity: sha512-7nF7C9fIPFEMHgEMEfgIlO9wDdZ8CyHw27rWciFZfHvHDReIiPhsYuzPRXsfvBCqFy1l8RRyyWV7QLM+ZhUJsQ==} engines: {node: '>=20.20.0'} @@ -2082,9 +2068,6 @@ packages: ohash@2.0.11: resolution: {integrity: sha512-RdR9FQrFwNBNXAr4GixM8YaRZRJ5PUWbKYbE5eOsrwAjJW0q2REGcf79oYPsLyskQCZG1PLN+S/K1V00joZAoQ==} - once@1.4.0: - resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==} - oniguruma-parser@0.12.2: resolution: {integrity: sha512-6HVa5oIrgMC6aA6WF6XyyqbhRPJrKR02L20+2+zpDtO5QAzGHAUGw5TKQvwi5vctNnRHkJYmjAhRVQF2EKdTQw==} @@ -2144,9 +2127,6 @@ packages: resolution: {integrity: sha512-cbrerZV+6rvdQrrD+iGMcZFEiiSrbv9Tfdkvnusy6y0x0GKBXREFg/Y65GhIfm0tnLntThhzCnfKwp1WRjeCyQ==} engines: {node: '>=14.0.0'} - pend@1.2.0: - resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} - piccolore@0.1.3: resolution: {integrity: sha512-o8bTeDWjE086iwKrROaDf31K0qC/BENdm15/uH9usSC/uZjJOKb2YGiVHfLY4GhwsERiPI1jmwI2XrA7ACOxVw==} @@ -2191,9 +2171,6 @@ packages: resolution: {integrity: sha512-cJ+oHTW1VAEa8cJslgmUZrc+sjRKgAKl3Zyse6+PV38hZe/V6Z14TbCuXcan9F9ghlz4QrFr2c92TNF82UkYHA==} engines: {node: '>=10'} - pump@3.0.4: - resolution: {integrity: sha512-VS7sjc6KR7e1ukRFhQSY5LM2uBWAUPiOPa/A3mkKmiMwSmRFUITt0xuj+/lesgnCv+dPIEYlkzrcyXgquIHMcA==} - punycode@2.3.1: resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} engines: {node: '>=6'} @@ -2777,9 +2754,6 @@ packages: resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==} engines: {node: '>=10'} - wrappy@1.0.2: - resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.20.0: resolution: {integrity: sha512-sAt8BhgNbzCtgGbt2OxmpuryO63ZoDk/sqaB/znQm94T4fCEsy/yV+7CdC1kJhOU9lboAEU7R3kquuycDoibVA==} engines: {node: '>=10.0.0'} @@ -2832,9 +2806,6 @@ packages: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} - yauzl@2.10.0: - resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} - yocto-queue@1.2.2: resolution: {integrity: sha512-4LCcse/U2MHZ63HAJVE+v71o7yOdIe4cZ70Wpf8D/IyjDKYQLV5GD46B+hSTjJsvV5PztjvHoU580EftxjDZFQ==} engines: {node: '>=12.20'} @@ -2991,7 +2962,7 @@ snapshots: dependencies: '@axe-core/webdriverjs': 4.11.3(selenium-webdriver@4.41.0) axe-core: 4.11.4 - chromedriver: 148.0.2 + chromedriver: 149.0.0 colors: 1.4.0 commander: 9.5.0 dotenv: 17.4.2 @@ -3182,8 +3153,7 @@ snapshots: '@fontsource/jetbrains-mono@5.2.8': {} - '@img/colour@1.1.0': - optional: true + '@img/colour@1.1.0': {} '@img/sharp-darwin-arm64@0.34.5': optionalDependencies: @@ -3621,11 +3591,6 @@ snapshots: '@types/unist@3.0.3': {} - '@types/yauzl@2.10.3': - dependencies: - '@types/node': 24.12.3 - optional: true - '@ungap/structured-clone@1.3.1': {} '@volar/kit@2.4.28(typescript@6.0.3)': @@ -3684,6 +3649,8 @@ snapshots: acorn@8.16.0: {} + adm-zip@0.5.17: {} + agent-base@9.0.0: {} ajv-draft-04@1.0.0(ajv@8.20.0): @@ -3849,8 +3816,6 @@ snapshots: boolbase@1.0.0: {} - buffer-crc32@0.2.13: {} - call-bind-apply-helpers@1.0.2: dependencies: es-errors: 1.3.0 @@ -3876,12 +3841,12 @@ snapshots: dependencies: readdirp: 5.0.0 - chromedriver@148.0.2: + chromedriver@149.0.0: dependencies: '@testim/chrome-version': 1.1.4 + adm-zip: 0.5.17 axios: 1.16.0 compare-versions: 6.1.1 - extract-zip: 2.0.1 proxy-agent: 8.0.1 proxy-from-env: 2.1.0 tcp-port-used: 1.0.2 @@ -4058,10 +4023,6 @@ snapshots: emoji-regex@8.0.0: {} - end-of-stream@1.4.5: - dependencies: - once: 1.4.0 - enhanced-resolve@5.21.1: dependencies: graceful-fs: 4.2.11 @@ -4192,16 +4153,6 @@ snapshots: extend@3.0.2: {} - extract-zip@2.0.1: - dependencies: - debug: 4.4.3 - get-stream: 5.2.0 - yauzl: 2.10.0 - optionalDependencies: - '@types/yauzl': 2.10.3 - transitivePeerDependencies: - - supports-color - fast-deep-equal@3.1.3: {} fast-string-truncated-width@3.0.3: {} @@ -4227,10 +4178,6 @@ snapshots: path-expression-matcher: 1.5.0 strnum: 2.3.0 - fd-slicer@1.1.0: - dependencies: - pend: 1.2.0 - fdir@6.5.0(picomatch@4.0.4): optionalDependencies: picomatch: 4.0.4 @@ -4282,10 +4229,6 @@ snapshots: dunder-proto: 1.0.1 es-object-atoms: 1.1.1 - get-stream@5.2.0: - dependencies: - pump: 3.0.4 - get-tsconfig@5.0.0-beta.4: dependencies: resolve-pkg-maps: 1.0.0 @@ -5149,10 +5092,6 @@ snapshots: ohash@2.0.11: {} - once@1.4.0: - dependencies: - wrappy: 1.0.2 - oniguruma-parser@0.12.2: {} oniguruma-to-es@4.3.6: @@ -5233,8 +5172,6 @@ snapshots: path-expression-matcher@1.5.0: {} - pend@1.2.0: {} - piccolore@0.1.3: {} picocolors@1.1.1: {} @@ -5274,11 +5211,6 @@ snapshots: proxy-from-env@2.1.0: {} - pump@3.0.4: - dependencies: - end-of-stream: 1.4.5 - once: 1.4.0 - punycode@2.3.1: {} quickjs-wasi@2.2.0: {} @@ -5551,7 +5483,6 @@ snapshots: '@img/sharp-win32-arm64': 0.34.5 '@img/sharp-win32-ia32': 0.34.5 '@img/sharp-win32-x64': 0.34.5 - optional: true shiki@4.0.2: dependencies: @@ -5943,8 +5874,6 @@ snapshots: string-width: 4.2.3 strip-ansi: 6.0.1 - wrappy@1.0.2: {} - ws@8.20.0: {} xml-name-validator@5.0.0: {} @@ -5987,11 +5916,6 @@ snapshots: y18n: 5.0.8 yargs-parser: 21.1.1 - yauzl@2.10.0: - dependencies: - buffer-crc32: 0.2.13 - fd-slicer: 1.1.0 - yocto-queue@1.2.2: {} yoga-layout@3.2.1: {} From 88bafdbf44cddc82f1c729efec667dd1bd92e36b Mon Sep 17 00:00:00 2001 From: Fajrian Aidil Pratama Date: Sat, 30 May 2026 01:55:09 +0800 Subject: [PATCH 4/5] ci: make release back-merge auto-resolve conflicts (prefer main, keep develop version) --- .github/workflows/release-finalize.yml | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release-finalize.yml b/.github/workflows/release-finalize.yml index bc343b8..114f584 100644 --- a/.github/workflows/release-finalize.yml +++ b/.github/workflows/release-finalize.yml @@ -179,18 +179,25 @@ jobs: git fetch origin develop main git checkout -B "$BACK_BRANCH" origin/develop - # Merge main into develop. Prefer develop's package.json if conflicting - # (develop already holds the next minor from release-prepare). - git merge --no-edit origin/main || { - if git diff --name-only --diff-filter=U | grep -q '^package.json$'; then - git checkout --ours package.json - git add package.json + # Merge main into develop, preferring main's content for any + # conflict (-X theirs) — main holds the shipped release. Then + # restore develop's package.json version (develop already carries + # the next minor from release-prepare). + git merge --no-edit -X theirs origin/main || { + UNMERGED=$(git diff --name-only --diff-filter=U) + if [ -z "$UNMERGED" ] || [ "$UNMERGED" = "package.json" ]; then + [ -n "$UNMERGED" ] && git checkout --ours package.json && git add package.json git commit --no-edit else - echo "::error::Unresolvable merge conflict on back-merge" + echo "::error::Unresolvable merge conflict on back-merge: $UNMERGED" exit 1 fi } + git checkout origin/develop -- package.json 2>/dev/null || true + if ! git diff --quiet package.json; then + git add package.json + git commit -m "chore: keep develop package.json version on back-merge" + fi git push -u origin "$BACK_BRANCH" gh pr create \ From 1647ddf4f878a4709228527e86ff66909c4cdf8d Mon Sep 17 00:00:00 2001 From: Fajrian Aidil Pratama Date: Mon, 27 Jul 2026 07:53:02 +0800 Subject: [PATCH 5/5] Hide Ulearna/Carwa/Reab portfolio references from the live site Removes Carwa and Reab case studies and the Ulearna Technology LTD client relationship from public pages, while keeping everything in git history for easy reversal: - Carwa and Reab content moved out of the portfolio collection's glob path (src/content/_hidden-portfolio/) plus a new draft flag on the portfolio schema, so their pages, portfolio-index cards, sitemap entries, and OG images no longer generate. - Ulearna Technology LTD removed from the client trust strip and the founder's past-employer strip (entries commented out, not deleted). - Home page and founder page copy reworded to drop the Ulearna name where it appeared inline (hero trust claims, founder narrative paragraphs), keeping the surrounding sentences intact. - Hero carousel on the home page and the founder page's "selected work" marquee no longer reference Carwa screenshots. - Estimator's portfolio-matching heuristic no longer scores the now- hidden carwa/reab slugs. - Dev-only component showcase page's demo card swapped to a generic placeholder instead of naming Reab/Ulearna. Refs banuacoder-gdg --- src/content.config.ts | 1 + .../carwa/cover.svg | 0 .../carwa/cover.webp | Bin .../carwa/index.en.mdx | 1 + .../carwa/index.id.mdx | 1 + .../carwa/screenshots/screenshot-1.webp | Bin .../carwa/screenshots/screenshot-2.webp | Bin .../carwa/screenshots/screenshot-3.webp | Bin .../carwa/screenshots/screenshot-4.webp | Bin .../carwa/screenshots/screenshot-clean-1.webp | Bin .../carwa/screenshots/screenshot-clean-2.webp | Bin .../carwa/thumbnail.svg | 0 .../reab/cover.svg | 0 .../reab/index.en.mdx | 1 + .../reab/index.id.mdx | 1 + .../reab/thumbnail.svg | 0 src/content/pages/home.en.mdx | 4 +-- src/content/pages/home.id.mdx | 4 +-- src/data/clients.ts | 15 +++++---- src/data/founder-experience.ts | 3 +- src/lib/estimator.ts | 8 +---- src/pages/dev/components.astro | 8 ++--- src/pages/en/estimate.astro | 2 +- src/pages/en/founder.astro | 12 ++++---- src/pages/en/index.astro | 28 ++--------------- src/pages/en/portfolio/[slug].astro | 4 +-- src/pages/en/portfolio/index.astro | 2 +- src/pages/estimate.astro | 2 +- src/pages/founder.astro | 12 ++++---- src/pages/index.astro | 29 ++---------------- src/pages/og/[...slug].png.ts | 2 +- src/pages/portfolio/[slug].astro | 4 +-- src/pages/portfolio/index.astro | 2 +- 33 files changed, 48 insertions(+), 98 deletions(-) rename src/content/{portfolio => _hidden-portfolio}/carwa/cover.svg (100%) rename src/content/{portfolio => _hidden-portfolio}/carwa/cover.webp (100%) rename src/content/{portfolio => _hidden-portfolio}/carwa/index.en.mdx (99%) rename src/content/{portfolio => _hidden-portfolio}/carwa/index.id.mdx (99%) rename src/content/{portfolio => _hidden-portfolio}/carwa/screenshots/screenshot-1.webp (100%) rename src/content/{portfolio => _hidden-portfolio}/carwa/screenshots/screenshot-2.webp (100%) rename src/content/{portfolio => _hidden-portfolio}/carwa/screenshots/screenshot-3.webp (100%) rename src/content/{portfolio => _hidden-portfolio}/carwa/screenshots/screenshot-4.webp (100%) rename src/content/{portfolio => _hidden-portfolio}/carwa/screenshots/screenshot-clean-1.webp (100%) rename src/content/{portfolio => _hidden-portfolio}/carwa/screenshots/screenshot-clean-2.webp (100%) rename src/content/{portfolio => _hidden-portfolio}/carwa/thumbnail.svg (100%) rename src/content/{portfolio => _hidden-portfolio}/reab/cover.svg (100%) rename src/content/{portfolio => _hidden-portfolio}/reab/index.en.mdx (99%) rename src/content/{portfolio => _hidden-portfolio}/reab/index.id.mdx (99%) rename src/content/{portfolio => _hidden-portfolio}/reab/thumbnail.svg (100%) diff --git a/src/content.config.ts b/src/content.config.ts index b40bc42..90386a6 100644 --- a/src/content.config.ts +++ b/src/content.config.ts @@ -24,6 +24,7 @@ const portfolio = defineCollection({ clientUrl: z.string().url().optional(), year: z.number().int(), status: z.enum(['live', 'maintained', 'archived']), + draft: z.boolean().default(false), cover: image(), thumbnail: image(), gallery: z.array(image()).optional(), diff --git a/src/content/portfolio/carwa/cover.svg b/src/content/_hidden-portfolio/carwa/cover.svg similarity index 100% rename from src/content/portfolio/carwa/cover.svg rename to src/content/_hidden-portfolio/carwa/cover.svg diff --git a/src/content/portfolio/carwa/cover.webp b/src/content/_hidden-portfolio/carwa/cover.webp similarity index 100% rename from src/content/portfolio/carwa/cover.webp rename to src/content/_hidden-portfolio/carwa/cover.webp diff --git a/src/content/portfolio/carwa/index.en.mdx b/src/content/_hidden-portfolio/carwa/index.en.mdx similarity index 99% rename from src/content/portfolio/carwa/index.en.mdx rename to src/content/_hidden-portfolio/carwa/index.en.mdx index 8986b4d..e4f0511 100644 --- a/src/content/portfolio/carwa/index.en.mdx +++ b/src/content/_hidden-portfolio/carwa/index.en.mdx @@ -5,6 +5,7 @@ bucket: consumer client: Ulearna Technology LTD year: 2024 status: maintained +draft: true cover: ./cover.webp thumbnail: ./thumbnail.svg summary: > diff --git a/src/content/portfolio/carwa/index.id.mdx b/src/content/_hidden-portfolio/carwa/index.id.mdx similarity index 99% rename from src/content/portfolio/carwa/index.id.mdx rename to src/content/_hidden-portfolio/carwa/index.id.mdx index 23829f6..6e11517 100644 --- a/src/content/portfolio/carwa/index.id.mdx +++ b/src/content/_hidden-portfolio/carwa/index.id.mdx @@ -5,6 +5,7 @@ bucket: consumer client: Ulearna Technology LTD year: 2024 status: maintained +draft: true cover: ./cover.webp thumbnail: ./thumbnail.svg summary: > diff --git a/src/content/portfolio/carwa/screenshots/screenshot-1.webp b/src/content/_hidden-portfolio/carwa/screenshots/screenshot-1.webp similarity index 100% rename from src/content/portfolio/carwa/screenshots/screenshot-1.webp rename to src/content/_hidden-portfolio/carwa/screenshots/screenshot-1.webp diff --git a/src/content/portfolio/carwa/screenshots/screenshot-2.webp b/src/content/_hidden-portfolio/carwa/screenshots/screenshot-2.webp similarity index 100% rename from src/content/portfolio/carwa/screenshots/screenshot-2.webp rename to src/content/_hidden-portfolio/carwa/screenshots/screenshot-2.webp diff --git a/src/content/portfolio/carwa/screenshots/screenshot-3.webp b/src/content/_hidden-portfolio/carwa/screenshots/screenshot-3.webp similarity index 100% rename from src/content/portfolio/carwa/screenshots/screenshot-3.webp rename to src/content/_hidden-portfolio/carwa/screenshots/screenshot-3.webp diff --git a/src/content/portfolio/carwa/screenshots/screenshot-4.webp b/src/content/_hidden-portfolio/carwa/screenshots/screenshot-4.webp similarity index 100% rename from src/content/portfolio/carwa/screenshots/screenshot-4.webp rename to src/content/_hidden-portfolio/carwa/screenshots/screenshot-4.webp diff --git a/src/content/portfolio/carwa/screenshots/screenshot-clean-1.webp b/src/content/_hidden-portfolio/carwa/screenshots/screenshot-clean-1.webp similarity index 100% rename from src/content/portfolio/carwa/screenshots/screenshot-clean-1.webp rename to src/content/_hidden-portfolio/carwa/screenshots/screenshot-clean-1.webp diff --git a/src/content/portfolio/carwa/screenshots/screenshot-clean-2.webp b/src/content/_hidden-portfolio/carwa/screenshots/screenshot-clean-2.webp similarity index 100% rename from src/content/portfolio/carwa/screenshots/screenshot-clean-2.webp rename to src/content/_hidden-portfolio/carwa/screenshots/screenshot-clean-2.webp diff --git a/src/content/portfolio/carwa/thumbnail.svg b/src/content/_hidden-portfolio/carwa/thumbnail.svg similarity index 100% rename from src/content/portfolio/carwa/thumbnail.svg rename to src/content/_hidden-portfolio/carwa/thumbnail.svg diff --git a/src/content/portfolio/reab/cover.svg b/src/content/_hidden-portfolio/reab/cover.svg similarity index 100% rename from src/content/portfolio/reab/cover.svg rename to src/content/_hidden-portfolio/reab/cover.svg diff --git a/src/content/portfolio/reab/index.en.mdx b/src/content/_hidden-portfolio/reab/index.en.mdx similarity index 99% rename from src/content/portfolio/reab/index.en.mdx rename to src/content/_hidden-portfolio/reab/index.en.mdx index 1204042..edbd938 100644 --- a/src/content/portfolio/reab/index.en.mdx +++ b/src/content/_hidden-portfolio/reab/index.en.mdx @@ -5,6 +5,7 @@ bucket: consumer client: Ulearna Technology LTD year: 2024 status: maintained +draft: true cover: ./cover.svg thumbnail: ./thumbnail.svg summary: > diff --git a/src/content/portfolio/reab/index.id.mdx b/src/content/_hidden-portfolio/reab/index.id.mdx similarity index 99% rename from src/content/portfolio/reab/index.id.mdx rename to src/content/_hidden-portfolio/reab/index.id.mdx index e2547ad..8d282e3 100644 --- a/src/content/portfolio/reab/index.id.mdx +++ b/src/content/_hidden-portfolio/reab/index.id.mdx @@ -5,6 +5,7 @@ bucket: consumer client: Ulearna Technology LTD year: 2024 status: maintained +draft: true cover: ./cover.svg thumbnail: ./thumbnail.svg summary: > diff --git a/src/content/portfolio/reab/thumbnail.svg b/src/content/_hidden-portfolio/reab/thumbnail.svg similarity index 100% rename from src/content/portfolio/reab/thumbnail.svg rename to src/content/_hidden-portfolio/reab/thumbnail.svg diff --git a/src/content/pages/home.en.mdx b/src/content/pages/home.en.mdx index c288ebd..2905c29 100644 --- a/src/content/pages/home.en.mdx +++ b/src/content/pages/home.en.mdx @@ -17,7 +17,7 @@ trustClaims: - label: "Founded in 2019" - label: "15+ shipped case studies" - label: "Engineering-led delivery" - - label: "Clients: Pemprov Sulteng · Pemkab Gowa · Ulearna (Dubai, UAE)" + - label: "Clients: Pemprov Sulteng · Pemkab Gowa" about: eyebrow: "ABOUT US" @@ -99,7 +99,7 @@ founder: marker: "[ 06 ]" sectionTitle: "Led by engineering experience" headline: "Led by engineering experience across product, platform, and operational systems" - narrative: "Ryan's experience spans consumer products for the international market (Dubai/UAE via Ulearna Technology LTD), public-sector and regional tax systems, and platform engineering at GoTo Financial, Reku, and Stockbit/Bibit. Banua Coder approaches every project with a combination of product thinking, engineering depth, and cross-context business operational understanding." + narrative: "Ryan's experience spans consumer products for the international market (Dubai/UAE), public-sector and regional tax systems, and platform engineering at GoTo Financial, Reku, and Stockbit/Bibit. Banua Coder approaches every project with a combination of product thinking, engineering depth, and cross-context business operational understanding." readMoreLabel: "Full founder profile" idealClients: diff --git a/src/content/pages/home.id.mdx b/src/content/pages/home.id.mdx index 312a94c..20fffba 100644 --- a/src/content/pages/home.id.mdx +++ b/src/content/pages/home.id.mdx @@ -17,7 +17,7 @@ trustClaims: - label: "Berdiri sejak 2019" - label: "15+ studi kasus dipublikasikan" - label: "Dibangun dengan disiplin engineering" - - label: "Klien: Pemprov Sulteng · Pemkab Gowa · Ulearna (Dubai)" + - label: "Klien: Pemprov Sulteng · Pemkab Gowa" about: eyebrow: "TENTANG KAMI" @@ -99,7 +99,7 @@ founder: marker: "[ 06 ]" sectionTitle: "Dipimpin oleh tangan engineer" headline: "Engineer yang pernah mengerjakan produk konsumen, platform skala besar, dan sistem operasional bisnis" - narrative: "Ryan pernah mengerjakan produk konsumen untuk pasar internasional (Dubai/UAE bersama Ulearna Technology LTD), sistem layanan publik dan pajak daerah, hingga produk skala jutaan pengguna di GoTo Financial, Reku, dan Stockbit/Bibit. Pengalaman ini membentuk cara Banua Coder mendekati setiap proyek—menggabungkan cara berpikir produk, kedalaman engineering, dan pemahaman operasional bisnis." + narrative: "Ryan pernah mengerjakan produk konsumen untuk pasar internasional (Dubai/UAE), sistem layanan publik dan pajak daerah, hingga produk skala jutaan pengguna di GoTo Financial, Reku, dan Stockbit/Bibit. Pengalaman ini membentuk cara Banua Coder mendekati setiap proyek—menggabungkan cara berpikir produk, kedalaman engineering, dan pemahaman operasional bisnis." readMoreLabel: "Profil lengkap founder" idealClients: diff --git a/src/data/clients.ts b/src/data/clients.ts index b507e90..b4c29d2 100644 --- a/src/data/clients.ts +++ b/src/data/clients.ts @@ -8,7 +8,6 @@ export type Client = { } // LICENSE NOTES: -// - ulearna.png: source https://ulearna.com (og:image asset). Nominative fair use for client identification. // - pemprov-sulteng.svg: https://commons.wikimedia.org/wiki/File:Coat_of_arms_of_Central_Sulawesi.svg — Public domain (PD-IDGov, Indonesian state emblem). Covers both PICO Sulteng and Surat BMPR engagements. // - pemkab-gowa.png: Pemkab Gowa coat of arms — Public domain (PD-IDGov, Indonesian state emblem). Sourced from owner's branding archive (cleaner asset than the Wikimedia commons version). // - pemkab-donggala.png: https://commons.wikimedia.org/wiki/File:Lambang_Kabupaten_Donggala.png — Public domain (PD-IDGov). Covers Siap Donggala (Mekari Talenta integration). @@ -24,13 +23,13 @@ export type Client = { // case study (src/content/portfolio/surat-bmpr/) where the partnership context matters. export const clients: Client[] = [ - { - name: 'Ulearna Technology LTD', - logo: 'ulearna.png', - url: 'https://ulearna.com', - tier: 'featured', - context: 'Dubai, UAE — international consumer products (Reab, Carwa)', - }, + // { + // name: 'Ulearna Technology LTD', + // logo: 'ulearna.png', + // url: 'https://ulearna.com', + // tier: 'featured', + // context: 'Dubai, UAE — international consumer products (Reab, Carwa)', + // }, { name: 'PT Brantas Inti Utama', logo: 'brantas-inti-utama.png', diff --git a/src/data/founder-experience.ts b/src/data/founder-experience.ts index fe76028..de8638c 100644 --- a/src/data/founder-experience.ts +++ b/src/data/founder-experience.ts @@ -4,11 +4,10 @@ export type FounderExperience = { company: string; logo: string; context: string // - goto-financial.png: https://commons.wikimedia.org/wiki/File:GoTo_Financial.png — Public domain (PD-IDGov / corporate brand mark). // - reku.png: https://reku.id/next/assets/images/logo/reku.png — nominative fair use for employer identification. // - stockbit.svg: https://stockbit.com/images/stockbit.svg — nominative fair use for employer identification. -// - ulearna.png: https://ulearna.com (og:image asset) — nominative fair use for employer identification. export const founderExperience: FounderExperience[] = [ { company: 'GoTo Financial', logo: 'goto-financial.png', context: 'Mobile platform engineering' }, { company: 'Reku', logo: 'reku.png', context: 'Mobile engineering' }, { company: 'Stockbit/Bibit', logo: 'stockbit.svg', context: 'Mobile platform' }, - { company: 'Ulearna', logo: 'ulearna.png', context: 'International product collaboration (Dubai, UAE)' }, + // { company: 'Ulearna', logo: 'ulearna.png', context: 'International product collaboration (Dubai, UAE)' }, ] diff --git a/src/lib/estimator.ts b/src/lib/estimator.ts index c118fc2..2c9ddc0 100644 --- a/src/lib/estimator.ts +++ b/src/lib/estimator.ts @@ -106,7 +106,7 @@ function buildTeam(input: EstimatorInput): string[] { } // ─── Portfolio matching ──────────────────────────────────────────────────── -const consumerSlugs = ['reab', 'carwa', 'caretaker'] +const consumerSlugs = ['caretaker'] const publicSlugs = ['pico-sulteng', 'patonro', 'lontara'] function matchPortfolio(input: EstimatorInput): string[] { @@ -124,16 +124,10 @@ function matchPortfolio(input: EstimatorInput): string[] { } if (features.includes('payments')) { - scores['carwa'] = (scores['carwa'] ?? 0) + 1 scores['patonro'] = (scores['patonro'] ?? 0) + 1 } - if (features.includes('realtime')) { - scores['carwa'] = (scores['carwa'] ?? 0) + 1 - } - if (features.includes('push')) { - scores['reab'] = (scores['reab'] ?? 0) + 1 scores['caretaker'] = (scores['caretaker'] ?? 0) + 1 } diff --git a/src/pages/dev/components.astro b/src/pages/dev/components.astro index 58ea3be..684c18b 100644 --- a/src/pages/dev/components.astro +++ b/src/pages/dev/components.astro @@ -294,12 +294,12 @@ import DeviceFrame from '../../components/interactive/DeviceFrame.astro'
!data.draft) const enPortfolio = allPortfolio.filter((p) => p.data.locale === 'en') const idPortfolio = allPortfolio.filter((p) => p.data.locale === 'id') diff --git a/src/pages/en/founder.astro b/src/pages/en/founder.astro index d69f66b..fcae2eb 100644 --- a/src/pages/en/founder.astro +++ b/src/pages/en/founder.astro @@ -16,8 +16,8 @@ import sikerjaShot1 from '../../content/portfolio/sikerja/screenshots/screenshot import sikerjaShot2 from '../../content/portfolio/sikerja/screenshots/screenshot-3.webp' import detexiShot1 from '../../content/portfolio/detexi/screenshots/screenshot-2.webp' import detexiShot2 from '../../content/portfolio/detexi/screenshots/screenshot-4.webp' -import carwaShot1 from '../../content/portfolio/carwa/screenshots/screenshot-2.webp' -import carwaShot2 from '../../content/portfolio/carwa/screenshots/screenshot-3.webp' +// import carwaShot1 from '../../content/portfolio/carwa/screenshots/screenshot-2.webp' +// import carwaShot2 from '../../content/portfolio/carwa/screenshots/screenshot-3.webp' import picoShot1 from '../../content/portfolio/pico-sulteng/screenshots/screenshot-1.webp' import picoShot2 from '../../content/portfolio/pico-sulteng/screenshots/screenshot-4.webp' import ambientImg from '../../assets/stock/clean-workspace-notebook.jpg' @@ -35,7 +35,7 @@ const selectedExperience = [ { company: 'GoTo Financial', context: 'Mobile platform engineering — large-scale fintech ecosystem' }, { company: 'Reku', context: 'Mobile engineering — crypto and digital investment application' }, { company: 'Stockbit / Bibit', context: 'Mobile platform — investment community and mutual fund application' }, - { company: 'Ulearna Technology LTD', context: 'International product collaboration — consumer-facing application for global market' }, + // { company: 'Ulearna Technology LTD', context: 'International product collaboration — consumer-facing application for global market' }, { company: 'Public Sector', context: 'Public digital systems — regional service and payment applications' }, ] @@ -207,7 +207,7 @@ const founderBreadcrumbSchema = { Ryan grew up in Central Sulawesi and built his career as a software engineer specializing in mobile engineering, platform systems, and digital product development. From early on, he was drawn to how large systems work from the inside — not just building requested features, but understanding architecture, tradeoffs, and the long-term implications of every technical decision.

- His career took him into product engineering environments rarely reached by engineers from regional Indonesia: GoTo Financial as Southeast Asia's largest fintech ecosystem, Reku and Stockbit/Bibit as consumer investment platforms serving millions of users, and international collaboration with Ulearna Technology LTD on products targeting a global market. He also worked on public-sector digital systems — regional tax and retribution service applications that demand a different kind of rigor around data trust and workflow clarity than typical consumer apps. + His career took him into product engineering environments rarely reached by engineers from regional Indonesia: GoTo Financial as Southeast Asia's largest fintech ecosystem, Reku and Stockbit/Bibit as consumer investment platforms serving millions of users, and international product collaboration targeting a global market. He also worked on public-sector digital systems — regional tax and retribution service applications that demand a different kind of rigor around data trust and workflow clarity than typical consumer apps.

Banua Coder was founded in 2019 from a desire to bring those engineering and product-thinking standards to a local context — businesses and organizations in regional Indonesia that need a technology partner they can genuinely rely on, not just a vendor that codes. Ryan founded Banua Coder on one conviction: the quality of digital solutions should not depend on where a business is located. @@ -356,8 +356,8 @@ const founderBreadcrumbSchema = { { src: detexiShot1, alt: "Detexi Doctor — search doctors by specialization", label: 'Detexi · 2023' }, { src: detexiShot2, alt: "Detexi Doctor — patient–doctor consultation flow", label: 'Detexi · 2023' }, // Group: Carwa - { src: carwaShot1, alt: "Carwa — live digital car auction interface", label: 'Carwa · Dubai · 2024' }, - { src: carwaShot2, alt: "Carwa — auction listing with vehicle specifications", label: 'Carwa · Dubai · 2024' }, + // { src: carwaShot1, alt: "Carwa — live digital car auction interface", label: 'Carwa · Dubai · 2024' }, + // { src: carwaShot2, alt: "Carwa — auction listing with vehicle specifications", label: 'Carwa · Dubai · 2024' }, // Group: PICO Sulteng { src: picoShot1, alt: "PICO Sulteng — provincial COVID-19 statistics dashboard", label: 'PICO Sulteng · 2021' }, { src: picoShot2, alt: "PICO Sulteng — regional case-distribution map", label: 'PICO Sulteng · 2021' }, diff --git a/src/pages/en/index.astro b/src/pages/en/index.astro index af410cc..0da8388 100644 --- a/src/pages/en/index.astro +++ b/src/pages/en/index.astro @@ -27,8 +27,6 @@ import heroSiapFront from '../../content/portfolio/siap-donggala/screenshots/scr import heroSiapBack from '../../content/portfolio/siap-donggala/screenshots/screenshot-3.webp' import heroDetexiFront from '../../content/portfolio/detexi/screenshots/screenshot-4.webp' import heroDetexiBack from '../../content/portfolio/detexi/screenshots/screenshot-5.webp' -import heroCarwaFront from '../../content/portfolio/carwa/screenshots/screenshot-clean-1.webp' -import heroCarwaBack from '../../content/portfolio/carwa/screenshots/screenshot-clean-2.webp' import { Coffee, Sparkles, Landmark, TrendingUp, Lightbulb, ArrowRight } from 'lucide-astro' const idealClientIcons: Record = { @@ -38,10 +36,9 @@ const idealClientIcons: Record = { 'trending-up': TrendingUp, 'lightbulb': Lightbulb, } -import heroCarwa from '../../content/portfolio/carwa/screenshots/screenshot-1.webp' // Load featured portfolio entries for EN locale -const allPortfolioEntries = await getCollection('portfolio') +const allPortfolioEntries = await getCollection('portfolio', ({ data }) => !data.draft) const featuredProjects = allPortfolioEntries .filter((p) => p.data.locale === 'en' && p.data.featured) .sort((a, b) => a.data.order - b.data.order) @@ -219,24 +216,13 @@ const orgSchema = { class="hero-shot-img" data-hero-slide /> -

- Carwa preview — Dubai digital car auction
-
- Pratinjau aplikasi Carwa — lelang mobil digital Dubai
diff --git a/src/pages/og/[...slug].png.ts b/src/pages/og/[...slug].png.ts index 7f45123..a33ea81 100644 --- a/src/pages/og/[...slug].png.ts +++ b/src/pages/og/[...slug].png.ts @@ -51,7 +51,7 @@ export const getStaticPaths: GetStaticPaths = async () => { routes.push(...staticPages) // ── Portfolio detail pages ───────────────────────────────────────────── - const allPortfolio = await getCollection('portfolio') + const allPortfolio = await getCollection('portfolio', ({ data }) => !data.draft) for (const entry of allPortfolio) { const prefix = entry.data.locale === 'en' ? 'en-portfolio-' : 'portfolio-' routes.push({ diff --git a/src/pages/portfolio/[slug].astro b/src/pages/portfolio/[slug].astro index 520dfd2..b728288 100644 --- a/src/pages/portfolio/[slug].astro +++ b/src/pages/portfolio/[slug].astro @@ -14,7 +14,7 @@ import Prose from '../../components/typography/Prose.astro' import { renderInlineMd } from '../../lib/inline-md' export async function getStaticPaths() { - const allPortfolio = await getCollection('portfolio') + const allPortfolio = await getCollection('portfolio', ({ data }) => !data.draft) const idEntries = allPortfolio.filter((p) => p.data.locale === 'id') return idEntries.map((entry) => ({ params: { slug: entry.data.slug }, @@ -27,7 +27,7 @@ const { data } = entry const { Content } = await render(entry) // "Next case study" — same bucket, sorted by order, cycling -const allPortfolio = await getCollection('portfolio') +const allPortfolio = await getCollection('portfolio', ({ data }) => !data.draft) const sameBucket = allPortfolio .filter((p) => p.data.locale === 'id' && p.data.bucket === data.bucket && p.data.slug !== data.slug) .sort((a, b) => a.data.order - b.data.order) diff --git a/src/pages/portfolio/index.astro b/src/pages/portfolio/index.astro index f7939c3..4c952b2 100644 --- a/src/pages/portfolio/index.astro +++ b/src/pages/portfolio/index.astro @@ -10,7 +10,7 @@ import CaseStudyCard from '../../components/cards/CaseStudyCard.astro' import BucketFilter from '../../components/interactive/BucketFilter.astro' // Load all ID portfolio entries, sorted by order -const allPortfolio = await getCollection('portfolio') +const allPortfolio = await getCollection('portfolio', ({ data }) => !data.draft) const projects = allPortfolio .filter((p) => p.data.locale === 'id') .sort((a, b) => a.data.order - b.data.order)