0.11.6 : add event and export ICS
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "harmony-back",
|
||||
"version": "0.11.5",
|
||||
"version": "0.11.6",
|
||||
"private": true,
|
||||
"description": "A Strapi application",
|
||||
"scripts": {
|
||||
|
||||
@@ -28,14 +28,14 @@
|
||||
"enum": [
|
||||
"concert",
|
||||
"festival",
|
||||
"salon",
|
||||
"trade show",
|
||||
"symposium",
|
||||
"concours",
|
||||
"competition",
|
||||
"masterclass",
|
||||
"atelier vocal",
|
||||
"conférence",
|
||||
"répétition",
|
||||
"sorties"
|
||||
"vocal_workshop",
|
||||
"conference",
|
||||
"rehearsal",
|
||||
"outings"
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
{
|
||||
"kind": "collectionType",
|
||||
"collectionName": "event_relationships",
|
||||
"info": {
|
||||
"singularName": "event-relationship",
|
||||
"pluralName": "event-relationships",
|
||||
"displayName": "EventRelationship",
|
||||
"description": ""
|
||||
},
|
||||
"options": {
|
||||
"draftAndPublish": false
|
||||
},
|
||||
"pluginOptions": {},
|
||||
"attributes": {
|
||||
"author": {
|
||||
"type": "relation",
|
||||
"relation": "oneToOne",
|
||||
"target": "plugin::users-permissions.user"
|
||||
},
|
||||
"contextType": {
|
||||
"type": "enumeration",
|
||||
"enum": [
|
||||
"user",
|
||||
"group",
|
||||
"choral",
|
||||
"system"
|
||||
]
|
||||
},
|
||||
"contextId": {
|
||||
"type": "integer"
|
||||
},
|
||||
"relation": {
|
||||
"type": "enumeration",
|
||||
"enum": [
|
||||
"owner",
|
||||
"interested",
|
||||
"registered"
|
||||
]
|
||||
},
|
||||
"metas": {
|
||||
"type": "json"
|
||||
},
|
||||
"event": {
|
||||
"type": "relation",
|
||||
"relation": "oneToOne",
|
||||
"target": "api::event.event"
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* event-relationship controller
|
||||
*/
|
||||
|
||||
import { factories } from '@strapi/strapi'
|
||||
|
||||
export default factories.createCoreController('api::event-relationship.event-relationship');
|
||||
7
src/api/event-relationship/routes/event-relationship.ts
Normal file
7
src/api/event-relationship/routes/event-relationship.ts
Normal file
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* event-relationship router
|
||||
*/
|
||||
|
||||
import { factories } from '@strapi/strapi';
|
||||
|
||||
export default factories.createCoreRouter('api::event-relationship.event-relationship');
|
||||
@@ -0,0 +1,7 @@
|
||||
/**
|
||||
* event-relationship service
|
||||
*/
|
||||
|
||||
import { factories } from '@strapi/strapi';
|
||||
|
||||
export default factories.createCoreService('api::event-relationship.event-relationship');
|
||||
@@ -35,6 +35,40 @@
|
||||
},
|
||||
"location": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": {
|
||||
"type": "enumeration",
|
||||
"enum": [
|
||||
"concert",
|
||||
"festival",
|
||||
"trade show",
|
||||
"symposium",
|
||||
"competition",
|
||||
"masterclass",
|
||||
"vocal_workshop",
|
||||
"conference",
|
||||
"rehearsal",
|
||||
"outings"
|
||||
]
|
||||
},
|
||||
"voice": {
|
||||
"type": "enumeration",
|
||||
"enum": [
|
||||
"soprano",
|
||||
"alto",
|
||||
"tenor",
|
||||
"bass",
|
||||
"mixed"
|
||||
]
|
||||
},
|
||||
"description": {
|
||||
"type": "text"
|
||||
},
|
||||
"size": {
|
||||
"type": "integer"
|
||||
},
|
||||
"isPublic": {
|
||||
"type": "boolean"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
93
src/api/event/controllers/applyEvent.ts
Normal file
93
src/api/event/controllers/applyEvent.ts
Normal file
@@ -0,0 +1,93 @@
|
||||
import type { Core } from "@strapi/strapi";
|
||||
import type { Context } from "koa";
|
||||
|
||||
/**
|
||||
* Controller pour gérer l'inscription d'un utilisateur à un événement
|
||||
* POST /events/:eventId/apply
|
||||
*/
|
||||
export default ({ strapi }: { strapi: Core.Strapi }) =>
|
||||
async function applyEvent(ctx: Context) {
|
||||
const userId = ctx.state.user?.id;
|
||||
const eventId = ctx.params.eventId;
|
||||
|
||||
// Validation des paramètres
|
||||
if (!userId) {
|
||||
return ctx.badRequest("User ID is required");
|
||||
}
|
||||
|
||||
if (!eventId || isNaN(parseInt(eventId))) {
|
||||
return ctx.badRequest("Event ID is required and must be a valid number");
|
||||
}
|
||||
|
||||
try {
|
||||
// Vérifier que l'événement existe
|
||||
const event = await strapi.db.query("api::event.event").findOne({
|
||||
where: { id: parseInt(eventId) },
|
||||
});
|
||||
|
||||
if (!event) {
|
||||
return ctx.notFound("Event not found");
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur n'est pas déjà inscrit
|
||||
const existingRelationship = await strapi.db
|
||||
.query("api::event-relationship.event-relationship")
|
||||
.findOne({
|
||||
where: {
|
||||
event: { id: parseInt(eventId) },
|
||||
contextType: "user",
|
||||
contextId: parseInt(userId),
|
||||
relation: { $in: ["registered", "interested"] },
|
||||
},
|
||||
});
|
||||
|
||||
if (existingRelationship) {
|
||||
return ctx.badRequest(
|
||||
"User is already registered or interested in this event"
|
||||
);
|
||||
}
|
||||
|
||||
// Créer la nouvelle relation d'inscription
|
||||
const eventRelationship = await strapi.db
|
||||
.query("api::event-relationship.event-relationship")
|
||||
.create({
|
||||
data: {
|
||||
author: parseInt(userId),
|
||||
event: parseInt(eventId),
|
||||
contextType: "user",
|
||||
contextId: parseInt(userId),
|
||||
relation: "registered",
|
||||
metas: {
|
||||
appliedAt: new Date().toISOString(),
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
// Populer les données pour la réponse
|
||||
const populatedRelationship = await strapi.db
|
||||
.query("api::event-relationship.event-relationship")
|
||||
.findOne({
|
||||
where: { id: eventRelationship.id },
|
||||
populate: {
|
||||
event: {
|
||||
populate: {
|
||||
choral: true,
|
||||
},
|
||||
},
|
||||
author: {
|
||||
populate: {
|
||||
avatar: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
ctx.send({
|
||||
data: populatedRelationship,
|
||||
message: "Successfully registered for the event",
|
||||
});
|
||||
} catch (error) {
|
||||
strapi.log.error("Error in applyEvent controller:", error);
|
||||
ctx.internalServerError(`Failed to register for event: ${error.message}`);
|
||||
}
|
||||
};
|
||||
@@ -2,6 +2,39 @@
|
||||
* event controller
|
||||
*/
|
||||
|
||||
import { factories } from '@strapi/strapi'
|
||||
import { factories } from "@strapi/strapi";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
|
||||
export default factories.createCoreController('api::event.event');
|
||||
export default factories.createCoreController(
|
||||
"api::event.event",
|
||||
({ strapi }) => {
|
||||
const controllersDir = __dirname;
|
||||
const controllers: Record<string, any> = {};
|
||||
|
||||
fs.readdirSync(controllersDir).forEach((file) => {
|
||||
// Ignorer le contrôleur principal + fichiers map
|
||||
if (file.startsWith("event.") || file.endsWith(".map")) return;
|
||||
|
||||
// On accepte .ts et .js
|
||||
const ext = path.extname(file);
|
||||
if (![".ts", ".js"].includes(ext)) return;
|
||||
|
||||
const name = path.basename(file, ext);
|
||||
const modulePath = path.join(controllersDir, file);
|
||||
const module = require(modulePath);
|
||||
|
||||
const handler = module.default;
|
||||
if (typeof handler === "function") {
|
||||
controllers[name] = handler({ strapi });
|
||||
}
|
||||
});
|
||||
|
||||
console.log(Object.keys(controllers));
|
||||
|
||||
return {
|
||||
// ✅ injection automatique des customs
|
||||
...controllers,
|
||||
} as any;
|
||||
}
|
||||
);
|
||||
|
||||
278
src/api/event/controllers/feed.ts
Normal file
278
src/api/event/controllers/feed.ts
Normal file
@@ -0,0 +1,278 @@
|
||||
import type { Core } from "@strapi/strapi";
|
||||
import type { Context } from "koa";
|
||||
|
||||
export default ({ strapi }: { strapi: Core.Strapi }) =>
|
||||
async function feed(ctx: Context) {
|
||||
const userId = ctx.state.user?.id;
|
||||
|
||||
if (!userId) return ctx.badRequest("userId is required");
|
||||
|
||||
// Récupérer et valider la query avec les fonctions de Strapi
|
||||
|
||||
const contentType = strapi.contentType(
|
||||
"api::event-relationship.event-relationship"
|
||||
);
|
||||
let limit: number;
|
||||
let start: number;
|
||||
|
||||
try {
|
||||
// Sanitize la query
|
||||
await strapi.contentAPI.validate.query(ctx.query, contentType, {
|
||||
auth: ctx.state.auth,
|
||||
});
|
||||
const sanitizedQueryParams = await strapi.contentAPI.sanitize.query(
|
||||
ctx.query,
|
||||
contentType,
|
||||
{ auth: ctx.state.auth }
|
||||
);
|
||||
|
||||
const { _limit = 20, _start = 0 } = sanitizedQueryParams;
|
||||
limit = Math.max(1, Math.min(parseInt(String(_limit)) || 20, 100)); // Entre 1 et 100
|
||||
start = Math.max(0, parseInt(String(_start)) || 0); // Minimum 0
|
||||
} catch (error) {
|
||||
return ctx.badRequest(`Invalid query parameters: ${error.message}`);
|
||||
}
|
||||
|
||||
const queryParams = {
|
||||
populate: {
|
||||
event: {
|
||||
populate: {
|
||||
choral: true,
|
||||
},
|
||||
},
|
||||
author: {
|
||||
populate: {
|
||||
avatar: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
sort: { createdAt: "desc" },
|
||||
pagination: {
|
||||
start,
|
||||
limit,
|
||||
},
|
||||
};
|
||||
|
||||
// 1️⃣ Récupérer les groupes de l'utilisateur
|
||||
const groups = await strapi.db
|
||||
.query("api::group-membership.group-membership")
|
||||
.findMany({
|
||||
where: { user: { id: parseInt(userId) } },
|
||||
populate: ["group"],
|
||||
});
|
||||
const groupIds = groups.map((g) => g.group.id);
|
||||
|
||||
// 2️⃣ Récupérer les amis (contacts acceptés) et les follows
|
||||
const friendsContacts = await strapi.db
|
||||
.query("api::contact.contact")
|
||||
.findMany({
|
||||
where: {
|
||||
$or: [
|
||||
{ owner: { id: parseInt(userId) } },
|
||||
{ user: { id: parseInt(userId) } },
|
||||
],
|
||||
state: "accepted",
|
||||
},
|
||||
populate: ["owner", "user"],
|
||||
});
|
||||
const friendIds = friendsContacts.map((c) =>
|
||||
c.owner.id !== parseInt(userId) ? c.owner.id : c.user.id
|
||||
);
|
||||
|
||||
// Récupérer les contacts suivis (follow)
|
||||
const followContacts = await strapi.db
|
||||
.query("api::contact.contact")
|
||||
.findMany({
|
||||
where: {
|
||||
owner: { id: parseInt(userId) },
|
||||
state: "follow",
|
||||
},
|
||||
populate: ["user"],
|
||||
});
|
||||
const followIds = followContacts.map((c) => c.user.id);
|
||||
|
||||
// 3️⃣ Récupérer les groupes où mes amis sont membres (en excluant mes propres groupes)
|
||||
const friendsGroupMemberships = await strapi.db
|
||||
.query("api::group-membership.group-membership")
|
||||
.findMany({
|
||||
where: { user: { id: friendIds } },
|
||||
populate: ["group"],
|
||||
});
|
||||
const friendsGroupIds = friendsGroupMemberships
|
||||
.map((membership) => membership.group.id)
|
||||
.filter((groupId) => !groupIds.includes(groupId)); // Exclure mes propres groupes
|
||||
|
||||
// 4️⃣ Récupérer le count total pour la pagination
|
||||
const totalCount = await strapi.db
|
||||
.query("api::event-relationship.event-relationship")
|
||||
.count({
|
||||
where: {
|
||||
relation: "owner",
|
||||
$or: [
|
||||
// EventRelationships de l'utilisateur courant
|
||||
{ author: { id: parseInt(userId) } },
|
||||
// EventRelationships des amis
|
||||
{ author: { id: friendIds } },
|
||||
// EventRelationships des contacts suivis
|
||||
{ author: { id: followIds } },
|
||||
// EventRelationships des groupes de l'utilisateur
|
||||
{ contextType: "group", contextId: groupIds },
|
||||
// EventRelationships des groupes des amis
|
||||
{ contextType: "group", contextId: friendsGroupIds },
|
||||
// EventRelationships système
|
||||
{ contextType: "system" },
|
||||
],
|
||||
},
|
||||
});
|
||||
|
||||
// 4️⃣ Récupérer le feed avec pagination
|
||||
const feed = await strapi.db
|
||||
.query("api::event-relationship.event-relationship")
|
||||
.findMany({
|
||||
where: {
|
||||
relation: "owner",
|
||||
$or: [
|
||||
// EventRelationships de l'utilisateur courant
|
||||
{ author: { id: parseInt(userId) } },
|
||||
// EventRelationships des amis
|
||||
{ author: { id: friendIds } },
|
||||
// EventRelationships des contacts suivis
|
||||
{ author: { id: followIds } },
|
||||
// EventRelationships des groupes de l'utilisateur
|
||||
{ contextType: "group", contextId: groupIds },
|
||||
// EventRelationships des groupes des amis
|
||||
{ contextType: "group", contextId: friendsGroupIds },
|
||||
// EventRelationships système
|
||||
{ contextType: "system" },
|
||||
],
|
||||
},
|
||||
...queryParams,
|
||||
});
|
||||
|
||||
// 5️⃣ Récupérer tous les groupes mentionnés dans le feed pour les populer
|
||||
const allGroupIds = [...new Set([...groupIds, ...friendsGroupIds])];
|
||||
const allGroups = await strapi.db.query("api::group.group").findMany({
|
||||
where: { id: allGroupIds },
|
||||
});
|
||||
|
||||
// Créer un map pour un accès rapide aux groupes par ID
|
||||
const groupsMap = new Map(allGroups.map((group) => [group.id, group]));
|
||||
|
||||
// 6️⃣ Récupérer les participants (registered) pour chaque événement du feed
|
||||
const eventIds = feed.filter((er) => er.event?.id).map((er) => er.event.id);
|
||||
|
||||
const registeredRelationships = await strapi.db
|
||||
.query("api::event-relationship.event-relationship")
|
||||
.findMany({
|
||||
where: {
|
||||
event: { id: eventIds },
|
||||
relation: { $in: ["registered", "interested", "pending"] },
|
||||
contextType: "user",
|
||||
},
|
||||
populate: ["event"],
|
||||
});
|
||||
|
||||
// Extraire les userIds et récupérer les Users complètement populés
|
||||
const userIds = [
|
||||
...new Set(registeredRelationships.map((er) => er.contextId)),
|
||||
];
|
||||
const users = await strapi.db
|
||||
.query("plugin::users-permissions.user")
|
||||
.findMany({
|
||||
where: { id: userIds },
|
||||
populate: {
|
||||
avatar: true,
|
||||
},
|
||||
});
|
||||
|
||||
// Créer une map des users par ID pour accès rapide
|
||||
const usersMap = new Map(users.map((user) => [user.id, user]));
|
||||
|
||||
// Grouper les participants par eventId
|
||||
const participantsByEventId = new Map<number, any[]>();
|
||||
registeredRelationships.forEach((er) => {
|
||||
const eventId = er.event?.id;
|
||||
if (eventId) {
|
||||
if (!participantsByEventId.has(eventId)) {
|
||||
participantsByEventId.set(eventId, []);
|
||||
}
|
||||
const user = usersMap.get(er.contextId);
|
||||
if (user) {
|
||||
participantsByEventId.get(eventId)!.push({
|
||||
relation: er.relation,
|
||||
createdAt: er.createdAt,
|
||||
user: user,
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// 7️⃣ Enrichir le feed avec les propriétés friend, member, contactFollow, group et registered participants
|
||||
const enrichedFeed = feed.map((eventRelationship) => {
|
||||
const authorId = eventRelationship.author?.id;
|
||||
const contextType = eventRelationship.contextType;
|
||||
const contextId = eventRelationship.contextId;
|
||||
const eventId = eventRelationship.event?.id;
|
||||
|
||||
// Vérifier si l'auteur est un ami
|
||||
const isFriend = authorId ? friendIds.includes(authorId) : false;
|
||||
|
||||
// Vérifier si l'auteur est un contact suivi
|
||||
const isContactFollow = authorId ? followIds.includes(authorId) : false;
|
||||
|
||||
// Vérifier si je suis membre du groupe (seulement pour les events de groupe)
|
||||
const isMember =
|
||||
contextType === "group" && contextId
|
||||
? groupIds.includes(contextId)
|
||||
: false;
|
||||
|
||||
// Ajouter l'objet group si contextType est "group"
|
||||
const group =
|
||||
contextType === "group" && contextId ? groupsMap.get(contextId) : null;
|
||||
|
||||
// Récupérer les participants enregistrés pour cet événement
|
||||
const registered = eventId
|
||||
? participantsByEventId.get(eventId) || []
|
||||
: [];
|
||||
|
||||
return {
|
||||
...eventRelationship,
|
||||
friend: isFriend,
|
||||
contactFollow: isContactFollow,
|
||||
member: isMember,
|
||||
...(group && { group }), // Ajouter group seulement s'il existe
|
||||
registered, // Ajouter les participants enregistrés
|
||||
};
|
||||
});
|
||||
|
||||
// Trier par createdAt (le plus récent en premier)
|
||||
const sortedFeed = enrichedFeed.sort((a, b) => {
|
||||
const dateA = a.event?.createdAt
|
||||
? new Date(a.event.createdAt).getTime()
|
||||
: 0;
|
||||
const dateB = b.event?.createdAt
|
||||
? new Date(b.event.createdAt).getTime()
|
||||
: 0;
|
||||
return dateB - dateA; // Ordre décroissant (plus récent en premier)
|
||||
});
|
||||
|
||||
// Calculer les métadonnées de pagination comme Strapi
|
||||
const pageSize = limit;
|
||||
const page = Math.floor(start / limit) + 1;
|
||||
const pageCount = Math.ceil(totalCount / limit);
|
||||
|
||||
// Retourner avec les métadonnées de pagination
|
||||
ctx.send({
|
||||
data: sortedFeed,
|
||||
meta: {
|
||||
pagination: {
|
||||
start,
|
||||
limit: pageSize,
|
||||
total: totalCount,
|
||||
page,
|
||||
pageSize,
|
||||
pageCount,
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
65
src/api/event/controllers/unapplyEvent.ts
Normal file
65
src/api/event/controllers/unapplyEvent.ts
Normal file
@@ -0,0 +1,65 @@
|
||||
import type { Core } from "@strapi/strapi";
|
||||
import type { Context } from "koa";
|
||||
|
||||
/**
|
||||
* Controller pour gérer la désinscription d'un utilisateur d'un événement
|
||||
* POST /events/:eventId/unapply
|
||||
*/
|
||||
export default ({ strapi }: { strapi: Core.Strapi }) =>
|
||||
async function unapplyEvent(ctx: Context) {
|
||||
const userId = ctx.state.user?.id;
|
||||
const eventId = ctx.params.eventId;
|
||||
|
||||
// Validation des paramètres
|
||||
if (!userId) {
|
||||
return ctx.badRequest("User ID is required");
|
||||
}
|
||||
|
||||
if (!eventId || isNaN(parseInt(eventId))) {
|
||||
return ctx.badRequest("Event ID is required and must be a valid number");
|
||||
}
|
||||
|
||||
try {
|
||||
// Vérifier que l'événement existe
|
||||
const event = await strapi.db.query("api::event.event").findOne({
|
||||
where: { id: parseInt(eventId) },
|
||||
});
|
||||
|
||||
if (!event) {
|
||||
return ctx.notFound("Event not found");
|
||||
}
|
||||
|
||||
// Vérifier que l'utilisateur est inscrit
|
||||
const existingRelationship = await strapi.db
|
||||
.query("api::event-relationship.event-relationship")
|
||||
.findOne({
|
||||
where: {
|
||||
event: { id: parseInt(eventId) },
|
||||
contextType: "user",
|
||||
contextId: parseInt(userId),
|
||||
relation: { $in: ["registered", "interested"] },
|
||||
},
|
||||
});
|
||||
|
||||
if (!existingRelationship) {
|
||||
return ctx.badRequest("User is not registered for this event");
|
||||
}
|
||||
|
||||
// Supprimer la relation d'inscription
|
||||
const deletedRelationship = await strapi.db
|
||||
.query("api::event-relationship.event-relationship")
|
||||
.delete({
|
||||
where: { id: existingRelationship.id },
|
||||
});
|
||||
|
||||
ctx.send({
|
||||
data: deletedRelationship,
|
||||
message: "Successfully unregistered from the event",
|
||||
});
|
||||
} catch (error) {
|
||||
strapi.log.error("Error in unapplyEvent controller:", error);
|
||||
ctx.internalServerError(
|
||||
`Failed to unregister from event: ${error.message}`
|
||||
);
|
||||
}
|
||||
};
|
||||
23
src/api/event/routes/custom.ts
Normal file
23
src/api/event/routes/custom.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Custom event routes
|
||||
*/
|
||||
|
||||
export default {
|
||||
routes: [
|
||||
{
|
||||
method: "GET",
|
||||
path: "/events/feed",
|
||||
handler: "event.feed",
|
||||
},
|
||||
{
|
||||
method: "POST",
|
||||
path: "/events/:eventId/apply",
|
||||
handler: "event.applyEvent",
|
||||
},
|
||||
{
|
||||
method: "POST",
|
||||
path: "/events/:eventId/unapply",
|
||||
handler: "event.unapplyEvent",
|
||||
},
|
||||
],
|
||||
};
|
||||
@@ -148,7 +148,7 @@ export default factories.createCoreController(
|
||||
});
|
||||
const followIds = followContacts.map((c) => c.user.id);
|
||||
|
||||
// Récupérer les contacts suivis (follow)
|
||||
// Récupérer les contacts bloqués (blocked)
|
||||
const blockedContacts = await strapi.db
|
||||
.query("api::contact.contact")
|
||||
.findMany({
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
75
types/generated/contentTypes.d.ts
vendored
75
types/generated/contentTypes.d.ts
vendored
@@ -947,14 +947,14 @@ export interface ApiEventOtherEventOther extends Struct.CollectionTypeSchema {
|
||||
[
|
||||
'concert',
|
||||
'festival',
|
||||
'salon',
|
||||
'trade show',
|
||||
'symposium',
|
||||
'concours',
|
||||
'competition',
|
||||
'masterclass',
|
||||
'atelier vocal',
|
||||
'conf\u00E9rence',
|
||||
'r\u00E9p\u00E9tition',
|
||||
'sorties',
|
||||
'vocal_workshop',
|
||||
'conference',
|
||||
'rehearsal',
|
||||
'outings',
|
||||
]
|
||||
>;
|
||||
updatedAt: Schema.Attribute.DateTime;
|
||||
@@ -963,6 +963,48 @@ export interface ApiEventOtherEventOther extends Struct.CollectionTypeSchema {
|
||||
};
|
||||
}
|
||||
|
||||
export interface ApiEventRelationshipEventRelationship
|
||||
extends Struct.CollectionTypeSchema {
|
||||
collectionName: 'event_relationships';
|
||||
info: {
|
||||
description: '';
|
||||
displayName: 'EventRelationship';
|
||||
pluralName: 'event-relationships';
|
||||
singularName: 'event-relationship';
|
||||
};
|
||||
options: {
|
||||
draftAndPublish: false;
|
||||
};
|
||||
attributes: {
|
||||
author: Schema.Attribute.Relation<
|
||||
'oneToOne',
|
||||
'plugin::users-permissions.user'
|
||||
>;
|
||||
contextId: Schema.Attribute.Integer;
|
||||
contextType: Schema.Attribute.Enumeration<
|
||||
['user', 'group', 'choral', 'system']
|
||||
>;
|
||||
createdAt: Schema.Attribute.DateTime;
|
||||
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||
Schema.Attribute.Private;
|
||||
event: Schema.Attribute.Relation<'oneToOne', 'api::event.event'>;
|
||||
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||
localizations: Schema.Attribute.Relation<
|
||||
'oneToMany',
|
||||
'api::event-relationship.event-relationship'
|
||||
> &
|
||||
Schema.Attribute.Private;
|
||||
metas: Schema.Attribute.JSON;
|
||||
publishedAt: Schema.Attribute.DateTime;
|
||||
relation: Schema.Attribute.Enumeration<
|
||||
['owner', 'interested', 'registered']
|
||||
>;
|
||||
updatedAt: Schema.Attribute.DateTime;
|
||||
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||
Schema.Attribute.Private;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ApiEventEvent extends Struct.CollectionTypeSchema {
|
||||
collectionName: 'events';
|
||||
info: {
|
||||
@@ -981,17 +1023,37 @@ export interface ApiEventEvent extends Struct.CollectionTypeSchema {
|
||||
createdAt: Schema.Attribute.DateTime;
|
||||
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||
Schema.Attribute.Private;
|
||||
description: Schema.Attribute.Text;
|
||||
end: Schema.Attribute.DateTime;
|
||||
isPublic: Schema.Attribute.Boolean;
|
||||
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||
localizations: Schema.Attribute.Relation<'oneToMany', 'api::event.event'> &
|
||||
Schema.Attribute.Private;
|
||||
location: Schema.Attribute.String;
|
||||
publishedAt: Schema.Attribute.DateTime;
|
||||
size: Schema.Attribute.Integer;
|
||||
start: Schema.Attribute.DateTime;
|
||||
title: Schema.Attribute.String;
|
||||
type: Schema.Attribute.Enumeration<
|
||||
[
|
||||
'concert',
|
||||
'festival',
|
||||
'trade show',
|
||||
'symposium',
|
||||
'competition',
|
||||
'masterclass',
|
||||
'vocal_workshop',
|
||||
'conference',
|
||||
'rehearsal',
|
||||
'outings',
|
||||
]
|
||||
>;
|
||||
updatedAt: Schema.Attribute.DateTime;
|
||||
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||
Schema.Attribute.Private;
|
||||
voice: Schema.Attribute.Enumeration<
|
||||
['soprano', 'alto', 'tenor', 'bass', 'mixed']
|
||||
>;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -1886,6 +1948,7 @@ declare module '@strapi/strapi' {
|
||||
'api::conversation.conversation': ApiConversationConversation;
|
||||
'api::direct-message.direct-message': ApiDirectMessageDirectMessage;
|
||||
'api::event-other.event-other': ApiEventOtherEventOther;
|
||||
'api::event-relationship.event-relationship': ApiEventRelationshipEventRelationship;
|
||||
'api::event.event': ApiEventEvent;
|
||||
'api::group-membership.group-membership': ApiGroupMembershipGroupMembership;
|
||||
'api::group.group': ApiGroupGroup;
|
||||
|
||||
Reference in New Issue
Block a user