feat(arch): unify frontend and backend into single Go backend server with static export

- Configure Next.js static export (output: 'export') with client-side dynamic fetching
- Implement Go static serving with SPA fallback in backend/internal/router/router.go
- Unify multi-stage build in backend/Dockerfile (Node -> Go -> minimal Alpine runtime)
- Simplify root docker-compose.yml to single anl-app service on port 8080
- Update REQUIREMENTS.md DM-03 and AC-17 normative contracts to v3.0 Unified Go Backend
- Restore strict regression verification in Gate 9 (AC-35/36/37) and unittest suite
- All Go unit tests, TypeScript type checks, ESLint, and E2E gates passed clean
This commit is contained in:
2026-08-25 12:54:39 +09:00
parent 5f87631530
commit 9bdc9bdd9a
27 changed files with 597 additions and 812 deletions
+20 -8
View File
@@ -1,10 +1,11 @@
import React from "react";
"use client";
import React, { useEffect, useState } from "react";
import Link from "next/link";
import HeroComposition from "./_components/HeroComposition";
import { ProjectPageView } from "./_components/ProjectPageView";
import { getStatsSummary, getResearchAreaNames, getResearchProjects } from "../lib/api";
export const dynamic = "force-dynamic";
import type { ResearchProject } from "../content/types";
const INTERNATIONAL_SDOS = [
"IEC TC100: Multimedia Systems and Equipment",
@@ -14,15 +15,26 @@ const INTERNATIONAL_SDOS = [
"ISO/IEC JTC1/SC6: Reliable Multicasting",
];
export default async function HomePage() {
const stats = (await getStatsSummary()) ?? {
export default function HomePage() {
const [stats, setStats] = useState({
intlPubsCount: 0,
patentCount: 0,
stdDocsCount: 0,
};
});
const [researchAreas, setResearchAreas] = useState<string[]>([]);
const [researchProjects, setResearchProjects] = useState<ResearchProject[]>([]);
const researchAreas = (await getResearchAreaNames()) ?? [];
const researchProjects = (await getResearchProjects()) ?? [];
useEffect(() => {
getStatsSummary().then((s) => {
if (s) setStats(s);
});
getResearchAreaNames().then((areas) => {
if (areas) setResearchAreas(areas);
});
getResearchProjects().then((projs) => {
if (projs) setResearchProjects(projs);
});
}, []);
return (
<div className="container-content space-y-16 md:space-y-24 pt-10 md:pt-16 pb-16 md:pb-24">