2026-06-12 14:36:35 +02:00

115 lines
3.7 KiB
TypeScript

import {
DataTypes,
Model,
type CreationOptional,
type InferAttributes,
type InferCreationAttributes,
type Sequelize,
} from 'sequelize';
import type { Db } from '@/db/types';
import type {
BelongsToGetAssociationMixin,
BelongsToSetAssociationMixin,
HasManyGetAssociationsMixin,
HasManySetAssociationsMixin,
} from 'sequelize';
import type { Campuses } from './campuses';
import type { Organizations } from './organizations';
import type { Users } from './users';
/**
* School tier (American Organization → School → Campus hierarchy). A school
* belongs to one organization and owns one or more campuses. The school head is
* the Principal (school scope); campuses keep their own per-campus `timezone`
* (a school may span timezones), so timezone is intentionally NOT on this model.
*/
export class Schools extends Model<
InferAttributes<Schools>,
InferCreationAttributes<Schools>
> {
declare id: CreationOptional<string>;
declare name: string;
declare code: string;
declare address: string | null;
declare phone: string | null;
declare email: string | null;
declare description: string | null;
declare active: CreationOptional<boolean>;
declare importHash: CreationOptional<string | null>;
declare organizationId: CreationOptional<string | null>;
declare createdById: CreationOptional<string | null>;
declare updatedById: CreationOptional<string | null>;
declare createdAt: CreationOptional<Date>;
declare updatedAt: CreationOptional<Date>;
declare deletedAt: CreationOptional<Date | null>;
declare getCampuses_school: HasManyGetAssociationsMixin<Campuses>;
declare setCampuses_school: HasManySetAssociationsMixin<Campuses, string>;
declare getOrganization: BelongsToGetAssociationMixin<Organizations>;
declare setOrganization: BelongsToSetAssociationMixin<Organizations, string>;
declare getCreatedBy: BelongsToGetAssociationMixin<Users>;
declare setCreatedBy: BelongsToSetAssociationMixin<Users, string>;
declare getUpdatedBy: BelongsToGetAssociationMixin<Users>;
declare setUpdatedBy: BelongsToSetAssociationMixin<Users, string>;
static associate(db: Db): void {
db.schools.hasMany(db.campuses, {
as: 'campuses_school',
foreignKey: { name: 'schoolId' },
constraints: false,
});
db.schools.belongsTo(db.organizations, {
as: 'organization',
foreignKey: { name: 'organizationId' },
constraints: false,
});
db.schools.belongsTo(db.users, { as: 'createdBy' });
db.schools.belongsTo(db.users, { as: 'updatedBy' });
}
}
export default function (sequelize: Sequelize): typeof Schools {
Schools.init(
{
id: {
type: DataTypes.UUID,
defaultValue: DataTypes.UUIDV4,
primaryKey: true,
},
name: { type: DataTypes.TEXT, allowNull: false },
code: { type: DataTypes.TEXT, allowNull: false },
address: { type: DataTypes.TEXT },
phone: { type: DataTypes.TEXT },
email: { type: DataTypes.TEXT },
description: { type: DataTypes.TEXT },
active: {
type: DataTypes.BOOLEAN,
allowNull: false,
defaultValue: false,
},
importHash: {
type: DataTypes.STRING(255),
allowNull: true,
unique: true,
},
organizationId: { type: DataTypes.UUID, allowNull: true },
createdById: { type: DataTypes.UUID, allowNull: true },
updatedById: { type: DataTypes.UUID, allowNull: true },
createdAt: { type: DataTypes.DATE },
updatedAt: { type: DataTypes.DATE },
deletedAt: { type: DataTypes.DATE },
},
{
sequelize,
modelName: 'schools',
timestamps: true,
paranoid: true,
freezeTableName: true,
},
);
return Schools;
}