CodeVetter · Repo Unpack · Behavior traces
strapi/strapi
The following traces were followed by reading implementations in execution order. Startup proceeds through registration, database synchronization, middleware/routing setup, and listening. REST creation continues through sanitization, document transforms, entry creation, and relation persistence. Authentication branches into legacy or refresh issuance, while publishing and uploading cross additional state boundaries.
- Startup begins at bin/strapi.js → runCLI → createCLI command factories → start action → createStrapi → new Strapi. The constructor loads configuration/internal services; start calls load only when isLoaded is false.
- load → register → bootstrap → isLoaded=true → listen. Registration invokes providers, plugin and user hooks; bootstrap runs db.init/schema.sync, middleware/routing, permissions and lifecycle hooks. listen mounts routers and binds a configured socket or host/port, then postListen logs startup and sends telemetry.
- REST creation follows generated POST /pluralName → scoped route registration → compose-endpoint authentication/authorization/policies → collection controller create. The controller validates query/body.data, sanitizes input, calls service.create, sanitizes output, and returns a transformed response with status 201.
- service.create → documents(uid).create → transaction-wrapped repository create → validateParams/status/locale transforms → entries.create → entity validation/components/transforms → db.query.create. Database insertion attaches relations and returns a reread entity; an explicitly published D&P create additionally calls publish before returning.packages/core/core/src/core-api/service/collection-type.ts#L65-68packages/core/core/src/services/document-service/repository.ts#L411-434packages/core/core/src/services/document-service/repository.ts#L776-785packages/core/core/src/services/document-service/entries.ts#L92-111packages/core/database/src/entity-manager/index.ts#L342-372
- Local login follows POST /auth/local → auth.callback → provider-enabled check → validateCallbackBody → user lookup → user.validatePassword/bcrypt.compare → email-confirmation and blocked checks. Legacy mode issues a JWT; refresh mode generates refresh then access tokens and returns either an HTTP-only refresh cookie or a refreshToken field.
- A protected Content API request runs authenticate → jwt.getToken → jwt.verify → fetchAuthenticatedUser → confirmation/block checks → role permissions → generateAbility. It stores user/session context; verify permits authenticated unscoped access or requires every configured scope to satisfy ability.can.packages/core/core/src/services/auth/index.ts#L99-120packages/plugins/users-permissions/server/src/services/jwt.js#L13-28packages/plugins/users-permissions/server/src/services/jwt.js#L66-101packages/plugins/users-permissions/server/src/strategies/users-permissions.js#L12-62packages/plugins/users-permissions/server/src/strategies/users-permissions.js#L85-112
- publish rejects an empty documentId, selects locale-matching drafts/old published rows, loads relation mappings, deletes old published versions, adds firstPublishedAt, creates published entries, synchronizes unidirectional/bidirectional/self relations, and schedules entry.publish events. The public publish method is transaction-wrapped and exists only for D&P types.
- Media upload follows upload → temporary directory creation → configured-size batches → enhanceAndValidateFile → uploadFileAndPersist → provider size check → image/nonimage upload → add metadata → MEDIA_CREATE. The local stream provider writes under static.public/uploads and sets a public URL; upload finally removes temporary work.