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 \ diff --git a/package.json b/package.json index 8490ff2..540f136 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "astro-scaffold", "type": "module", - "version": "1.0.1", + "version": "1.1.0", "engines": { "node": ">=22.12.0" }, 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)