Skip to content

Serveur Admin

createAdminServer génère une interface admin zéro-JS servie depuis une Firebase HTTPS Function.

Fonctionnalités :

  • Dashboard listant tous les repositories
  • Liste de documents avec pagination curseur, colonnes triables, sélecteur de lignes par page
  • Barre de filtres générée depuis fieldsConfig (champs avec le rôle "filterable")
  • Formulaires création / édition générés depuis le schéma Zod
  • Colonnes d'action relationnelles (naviguer vers le repo lié)
  • Authentification HTTP Basic ou middleware custom

Configuration de base

typescript
import { onRequest } from "firebase-functions/https";
import { createAdminServer } from "@lpdjs/firestore-repo-service/servers/admin";

const adminHandler = createAdminServer({
    httpsOptions: { invoker: "public" },
    basePath: "/admin",
    auth: {
      type:     "basic",
      realm:    "Admin",
      username: "admin",
      password: process.env.ADMIN_PASSWORD!,
    },
    repos: {
      users: {
        repo: repos.users,
        path: "users",
        fieldsConfig: {
          name:     ["create", "mutable", "filterable"],
          email:    ["create", "mutable", "filterable"],
          age:      ["create", "mutable", "filterable"],
          isActive: ["create", "mutable", "filterable"],
          docId:    ["filterable"],
        },
        allowDelete: true,
      },
      posts: {
        repo: repos.posts,
        path: "posts",
        fieldsConfig: {
          title:   ["create", "mutable"],
          content: ["create", "mutable"],
          status:  ["create", "mutable", "filterable"],
          userId:  ["create", "filterable"],
        },
        relationalFields: [
          { key: "userId", column: "Auteur" },
        ],
        allowDelete: false,
      },
    },
  });

export const admin = onRequest(adminHandler.httpsOptions!, adminHandler);

Options AdminRepoConfig

ChampTypeDéfautDescription
repoConfiguredRepositoryrequisInstance du repository
pathstringrequisChemin affiché dans l'UI
schemaZodObjectautoSchéma Zod (auto-détecté avec createRepositoryConfig(schema))
documentKeystring"docId"Champ utilisé comme ID de document
listColumnsstring[]all keysColonnes affichées dans la liste
pageSizenumber25Nombre de lignes par page par défaut
fieldsConfigRecord<FieldPath, FieldRole[]>all keysConfig par champ : "create", "mutable", "filterable"
allowDeletebooleanfalseAfficher le bouton Supprimer
relationalFields{ key, column }[]aucunColonnes boutons relationnelles

Champs en dot-notation

typescript
fieldsConfig: {
  status:           ["filterable"],
  "address.city":   ["create", "mutable", "filterable"],
  "address.street": ["create", "mutable", "filterable"],
  title:            ["create", "mutable"],
}

Champs relationnels

typescript
// Sur posts : bouton "Auteur" → /users?fv_docId=<post.userId>
relationalFields: [{ key: "userId", column: "Auteur" }]

// Sur users : bouton "Posts" → /posts?fv_userId=<user.docId>
relationalFields: [{ key: "docId", column: "Posts" }]

Contrôles de pagination

  • Navigation curseur : ← Précédent / Suivant →
  • Lignes par page : [10] [25] [50] [100] (querystring ?ps=N)
  • Tri par colonne : clic sur l'en-tête (querystring ?ob=champ&od=asc|desc)
  • Filtres : persistés à travers la pagination

Authentification

HTTP Basic Auth

typescript
auth: { type: "basic", realm: "Zone Admin", username: "admin", password: "secret" }

Middleware custom

typescript
auth: async (req, res, next) => {
  if (req.headers["x-api-key"] !== process.env.API_KEY) {
    res.status(401).send("Non autorisé");
    return;
  }
  next();
}

Firebase HttpsOptions

Passez n'importe quelle option HttpsOptions (invoker, region, memory, etc.) via httpsOptions. Les options sont attachées au handler retourné pour un usage facile avec onRequest() :

typescript
const handler = createAdminServer({
  httpsOptions: { invoker: "public", memory: "512MiB" },
  // ...
});

export const admin = onRequest(handler.httpsOptions!, handler);

Options disponibles : invoker, region, memory, timeoutSeconds, minInstances, maxInstances, concurrency, cors, serviceAccount, secrets, etc.

Serveur de pagination API

typescript
import { createPaginationFunction } from "@lpdjs/firestore-repo-service/servers/pagination";
import z from "zod";

export const postsApi = onRequest(
  createPaginationFunction(repos.posts, {
    schema:          z.object({ status: z.enum(["draft", "published"]).optional() }),
    defaultPageSize: 20,
    maxPageSize:     100,
    cors:            true,
  }),
);