feat(geoportal-v2): export toolbar + Semnez ca picker + CF intern/Extras split
V2 panel toolbar replaces the single "Comandă CF" button with two rows:
[Încadrare] [Pl. situație] [Coord.] [DXF] ← 4 exports
[CF intern] [Extras CF] ← 2 CF flows
Each export button pops an inline modal:
- PIZ / PAD: SignAsPicker (PFA / PJA radio list, manual-add inline,
co-signer slot on PIZ) + basemap toggle (google / orto for PIZ).
- Coord / DXF: no picker — single-click download via JWT proxy.
"CF intern" is the free copycf flow from eTerra (proxied via gis-api);
"Extras CF" keeps the existing CfOrderModal (1 credit ePay). The two
modes are now visually balanced as a 2-button row.
Sign-as picker rows merge user-owned Signatory table entries with the
SIGN_AS_DEFAULT_OPTIONS env-driven fallback (org-wide hardcoded options;
defaults seed two Studii de teren entries — Tiurbe PFA + SRL PJA). New
rows added via the picker's "Adaugă autorizație" inline form write to
the Signatory table; ENV rows are read-only.
Architots side ships fully:
- prisma Signatory model + ALTER TABLE applied (per the schema-drift
feedback memory).
- /api/sign-as-options (GET, POST) + /api/sign-as-options/[id]
(PATCH, DELETE).
- /api/cf-intern/order and /api/gis/parcel/[id]/{piz,pad,coords,dxf}
proxy routes — auth check + JWT forward, stream binary back.
- gis-api thin client extended with the matching exports.* namespace.
Until the gis-api endpoints ship (next session — full spec in
docs/plans/005-gis-api-export-endpoints.md), each export proxy returns
501 "…urmează" with a Romanian message so the modal shows what's
coming instead of a hard error.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,60 @@
|
||||
// POST /api/cf-intern/order
|
||||
//
|
||||
// Internal-circuit CF download — free eTerra `copycf` flow proxied via
|
||||
// gis-api. Body: { nrCadastral, siruta }. Streams the PDF back.
|
||||
//
|
||||
// Until gis-api ships POST /api/v1/enrichment/cf-intern (see docs/plans/005-…),
|
||||
// this route surfaces gis-api's 404 as a friendly "shipping next" message.
|
||||
|
||||
import { NextResponse } from "next/server";
|
||||
import { getAuthSession } from "@/core/auth/require-auth";
|
||||
import { gisApi, GisApiError } from "@/lib/gis-api-client";
|
||||
|
||||
export const runtime = "nodejs";
|
||||
export const dynamic = "force-dynamic";
|
||||
|
||||
type Body = { nrCadastral?: string; siruta?: string };
|
||||
|
||||
export async function POST(request: Request) {
|
||||
const session = await getAuthSession();
|
||||
if (!session) return NextResponse.json({ error: "Unauthorized" }, { status: 401 });
|
||||
|
||||
const body = (await request.json()) as Body;
|
||||
if (!body.nrCadastral?.trim() || !body.siruta?.trim()) {
|
||||
return NextResponse.json(
|
||||
{ error: "missing_params", message: "Necesare: nrCadastral, siruta." },
|
||||
{ status: 400 },
|
||||
);
|
||||
}
|
||||
|
||||
try {
|
||||
const upstream = await gisApi.exports.cfIntern({
|
||||
nrCadastral: body.nrCadastral.trim(),
|
||||
siruta: body.siruta.trim(),
|
||||
});
|
||||
const headers = new Headers();
|
||||
headers.set("Content-Type", upstream.headers.get("Content-Type") ?? "application/pdf");
|
||||
const cd = upstream.headers.get("Content-Disposition");
|
||||
if (cd) headers.set("Content-Disposition", cd);
|
||||
return new NextResponse(upstream.body, { status: 200, headers });
|
||||
} catch (err) {
|
||||
if (err instanceof GisApiError) {
|
||||
if (err.status === 404) {
|
||||
return NextResponse.json(
|
||||
{
|
||||
error: "endpoint_not_deployed",
|
||||
message:
|
||||
"CF intern urmează — endpoint-ul gis-api se livrează în sesiunea următoare.",
|
||||
},
|
||||
{ status: 501 },
|
||||
);
|
||||
}
|
||||
return NextResponse.json(
|
||||
{ error: err.code, body: err.body },
|
||||
{ status: err.status },
|
||||
);
|
||||
}
|
||||
const msg = err instanceof Error ? err.message : String(err);
|
||||
return NextResponse.json({ error: "internal_error", hint: msg.slice(0, 200) }, { status: 500 });
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user