Models
Models
Models define the entities and data structures used throughout the application.
The OpenSya runtime automatically discovers, registers and integrates models into the generated backend runtime.
Filesystem Structure
Models are placed inside the server/database/models directory.
server/database/models/
├── candidate.ts
├── interview.ts
└── feedback.ts
Each file represents a database model automatically discovered by the runtime.
Creating a Model
A model is defined using the Model type.
import { Model } from '#core/nest/types';
const model = {
schema: {
firstName: { type: String, required: true },
lastName: { type: String, required: true },
email: { type: String, required: true, unique: true },
skills: [{ type: String }],
available: { type: Boolean, default: true },
},
} satisfies Model;
export default model;
The runtime automatically discovers and registers the model.
Accessing Models
Models are accessed through the OpenSya runtime using the getModel() helper.
const candidateModel = getModel('Candidate');
The runtime automatically returns the registered model instance.
Example:
const candidate = await getModel('Candidate').findById(candidateId);
Model Registry
All discovered models are automatically registered inside the OpenSya runtime registry.
server/database/models/candidate.ts
↓
Registered as:
Candidate
This allows models to be accessed consistently across the entire application without manual imports.
Models should generally be accessed through getModel() rather than direct runtime imports.
::
Explicit Model Name
You can explicitly define the model name using the name property.
import { Model } from '#core/nest/types';
const model: Model = {
name: 'InterviewFeedback',
schema: {
rating: { type: Number, required: true },
comment: { type: String },
recommended: { type: Boolean, default: false },
},
};
export default model;
Automatic Model Name Inference
If the model name is not provided, OpenSya automatically infers it from the filename.
Example:
server/database/models/candidate.ts
↓
Candidate
server/database/models/interview-feedback.ts
↓
InterviewFeedback
Schema Definitions
Schemas are fully compatible with the OpenSya database runtime and support standard schema definitions.
import { Model } from '#core/nest/types';
const model = {
schema: {
status: {
type: String,
required: true,
enum: ['pending', 'reviewed', 'accepted', 'rejected'],
},
score: {
type: Number,
default: 0,
},
archived: {
type: Boolean,
default: false,
},
},
} satisfies Model;
export default model;
Strong Typing
Models can also be strongly typed using TypeScript generics.
import { Model } from '#core/nest/types';
type MediaSchema = {
filename: string;
type: string;
size: number;
};
const model: Model<MediaSchema> = {
schema: {
filename: { type: String, required: true },
type: { type: String, required: true },
size: { type: Number, required: true },
},
};
export default model;
This improves:
- Type safety
- IDE autocompletion
- Shared runtime contracts
- Developer experience
Runtime Discovery
During startup, OpenSya automatically:
- Discovers model files
- Registers schemas
- Loads plugins
- Generates typings
- Integrates models into the generated runtime
Filesystem Discovery
↓
Model Registration
↓
Plugin Loading
↓
Type Generation
↓
Runtime Integration
Overriding Native Models
OpenSya allows overriding native models by declaring another model with the same name.
This can be useful for advanced customizations and infrastructure extensions.
Example:
server/database/models/user.ts
↓
Overrides native User model
This feature is intended for advanced use cases and infrastructure-level customizations.
Philosophy
OpenSya models are designed to remain:
- Flexible
- Modular
- Runtime-aware
- Strongly typed
- Scalable
The goal is to make recruitment and business infrastructures easier to evolve without introducing unnecessary schema rigidity.