SnapAPI/src/routes/signup.ts
SnapAPI CEO 713cc30ac7
Some checks failed
Deploy to Staging / build-and-deploy (push) Failing after 10m13s
fix: code-driven OpenAPI docs — replace static JSON with swagger-jsdoc
BREAKING: OpenAPI spec is now generated from JSDoc annotations on route
handlers at startup, eliminating drift between code and documentation.

What was wrong:
- Static public/openapi.json was manually maintained and could drift
- Missing endpoints: signup, billing (checkout/success/webhook)
- Signup route was imported but never mounted (dead code)

What was fixed:
- Added swagger-jsdoc to generate OpenAPI spec from JSDoc on route files
- Every route handler now has @openapi JSDoc annotation as source of truth
- Spec served dynamically at GET /openapi.json (no static file)
- Deleted public/openapi.json
- Documented all missing endpoints (signup, billing x3)
- Mounted /v1/signup route
- All 9 screenshot params documented with types, ranges, defaults
2026-02-20 07:32:37 +00:00

80 lines
2.4 KiB
TypeScript

import { Router } from "express";
import { createKey } from "../services/keys.js";
import logger from "../services/logger.js";
export const signupRouter = Router();
// Simple signup: email → instant API key (no verification for now)
/**
* @openapi
* /v1/signup/free:
* post:
* tags: [Signup]
* summary: Create a free account
* description: Sign up with an email to get a free API key (100 screenshots/month).
* operationId: signupFree
* requestBody:
* required: true
* content:
* application/json:
* schema:
* type: object
* required: [email]
* properties:
* email:
* type: string
* format: email
* description: Your email address
* example: "user@example.com"
* responses:
* 200:
* description: API key created
* content:
* application/json:
* schema:
* type: object
* properties:
* apiKey:
* type: string
* description: Your new API key
* tier:
* type: string
* example: free
* limit:
* type: integer
* example: 100
* message:
* type: string
* 400:
* description: Invalid email
* content:
* application/json:
* schema: { $ref: "#/components/schemas/Error" }
* 500:
* description: Signup failed
* content:
* application/json:
* schema: { $ref: "#/components/schemas/Error" }
*/
signupRouter.post("/free", async (req, res) => {
const { email } = req.body;
if (!email || typeof email !== "string" || !email.includes("@")) {
res.status(400).json({ error: "Valid email required" });
return;
}
try {
const key = await createKey(email.toLowerCase().trim(), "free");
logger.info({ email: email.slice(0, 3) + "***" }, "Free signup");
res.json({
apiKey: key.key,
tier: "free",
limit: 100,
message: "Your API key is ready! 100 free screenshots/month.",
});
} catch (err: any) {
logger.error({ err }, "Signup failed");
res.status(500).json({ error: "Signup failed" });
}
});