Merge pull request 'work' (#1) from work into main
Reviewed-on: harmony/harmony-back#1
This commit is contained in:
80
config/cron-tasks.ts
Normal file
80
config/cron-tasks.ts
Normal file
@@ -0,0 +1,80 @@
|
|||||||
|
interface GNewsArticle {
|
||||||
|
title: string;
|
||||||
|
description: string;
|
||||||
|
url: string;
|
||||||
|
image: string;
|
||||||
|
publishedAt: string;
|
||||||
|
source: {
|
||||||
|
name: string;
|
||||||
|
url: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
type GNewsResponse = {
|
||||||
|
articles: GNewsArticle[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export default {
|
||||||
|
/**
|
||||||
|
* Simple example.
|
||||||
|
* Every monday at 1am.
|
||||||
|
*/
|
||||||
|
|
||||||
|
GNEWS: {
|
||||||
|
task: async ({ strapi }) => {
|
||||||
|
// Add your own logic here (e.g. send a queue of email, create a database backup, etc.).
|
||||||
|
const API_KEY = "b3760544f6efb233f19d32fe78cc1300";
|
||||||
|
const keywords = ["chorale"].join("+");
|
||||||
|
const url = `https://gnews.io/api/v4/search?q=${keywords}&lang=fr&max=10&token=${API_KEY}`;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const response = await fetch(url);
|
||||||
|
const data = (await response.json()) as GNewsResponse;
|
||||||
|
|
||||||
|
const articles: GNewsArticle[] = data.articles;
|
||||||
|
|
||||||
|
for (const article of articles) {
|
||||||
|
const alreadyExists = await strapi.db
|
||||||
|
.query("api::post.post")
|
||||||
|
.findOne({
|
||||||
|
where: { url: article.url },
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!alreadyExists) {
|
||||||
|
const post = await strapi.db.query("api::post.post").create({
|
||||||
|
data: {
|
||||||
|
title: article.title,
|
||||||
|
content: article.description,
|
||||||
|
url: article.url,
|
||||||
|
imageUrl: article.image,
|
||||||
|
source: article.source.name,
|
||||||
|
published_at: article.publishedAt,
|
||||||
|
//is_auto_generated: true,
|
||||||
|
category: "photo",
|
||||||
|
author: 14,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
// Créer le postOwnership associé
|
||||||
|
await strapi.db.query("api::post-ownership.post-ownership").create({
|
||||||
|
data: {
|
||||||
|
post: post.id,
|
||||||
|
contextType: "system",
|
||||||
|
relation: "owner",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
strapi.log.info(`🆕 Article créé : ${article.title}`);
|
||||||
|
} else {
|
||||||
|
strapi.log.info(`🔁 Article déjà existant : ${article.title}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
strapi.log.error("❌ Erreur lors du fetch GNews :", error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: {
|
||||||
|
rule: "0 0 8 * * *",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
@@ -1,7 +1,13 @@
|
|||||||
|
import cronTasks from "./cron-tasks";
|
||||||
|
|
||||||
export default ({ env }) => ({
|
export default ({ env }) => ({
|
||||||
host: env('HOST', '0.0.0.0'),
|
host: env("HOST", "0.0.0.0"),
|
||||||
port: env.int('PORT', 1337),
|
port: env.int("PORT", 1337),
|
||||||
app: {
|
app: {
|
||||||
keys: env.array('APP_KEYS'),
|
keys: env.array("APP_KEYS"),
|
||||||
|
},
|
||||||
|
cron: {
|
||||||
|
enabled: true,
|
||||||
|
tasks: cronTasks,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
63
src/api/ad/content-types/ad/schema.json
Normal file
63
src/api/ad/content-types/ad/schema.json
Normal file
@@ -0,0 +1,63 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "ads",
|
||||||
|
"info": {
|
||||||
|
"singularName": "ad",
|
||||||
|
"pluralName": "ads",
|
||||||
|
"displayName": "Ad",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"hire",
|
||||||
|
"equipment",
|
||||||
|
"management",
|
||||||
|
"sheetmusic",
|
||||||
|
"local"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"validUntil": {
|
||||||
|
"type": "date"
|
||||||
|
},
|
||||||
|
"author": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToOne",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
},
|
||||||
|
"views": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"applies": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"location": {
|
||||||
|
"type": "component",
|
||||||
|
"repeatable": false,
|
||||||
|
"component": "address.full-address"
|
||||||
|
},
|
||||||
|
"contactname": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"contactemail": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"contactphone": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"featured": {
|
||||||
|
"type": "boolean"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/api/ad/controllers/ad.ts
Normal file
7
src/api/ad/controllers/ad.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* ad controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi'
|
||||||
|
|
||||||
|
export default factories.createCoreController('api::ad.ad');
|
||||||
7
src/api/ad/routes/ad.ts
Normal file
7
src/api/ad/routes/ad.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* ad router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::ad.ad');
|
||||||
7
src/api/ad/services/ad.ts
Normal file
7
src/api/ad/services/ad.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* ad service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::ad.ad');
|
||||||
34
src/api/comment/content-types/comment/schema.json
Normal file
34
src/api/comment/content-types/comment/schema.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "comments",
|
||||||
|
"info": {
|
||||||
|
"singularName": "comment",
|
||||||
|
"pluralName": "comments",
|
||||||
|
"displayName": "Comment",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"content": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"likes": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToOne",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
},
|
||||||
|
"replies": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::comment.comment"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/api/comment/controllers/comment.ts
Normal file
7
src/api/comment/controllers/comment.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* comment controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi'
|
||||||
|
|
||||||
|
export default factories.createCoreController('api::comment.comment');
|
||||||
7
src/api/comment/routes/comment.ts
Normal file
7
src/api/comment/routes/comment.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* comment router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::comment.comment');
|
||||||
7
src/api/comment/services/comment.ts
Normal file
7
src/api/comment/services/comment.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* comment service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::comment.comment');
|
||||||
33
src/api/contact-meta/content-types/contact-meta/schema.json
Normal file
33
src/api/contact-meta/content-types/contact-meta/schema.json
Normal file
@@ -0,0 +1,33 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "contact_metas",
|
||||||
|
"info": {
|
||||||
|
"singularName": "contact-meta",
|
||||||
|
"pluralName": "contact-metas",
|
||||||
|
"displayName": "ContactMeta"
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"contact": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "manyToOne",
|
||||||
|
"target": "api::contact.contact",
|
||||||
|
"inversedBy": "metas"
|
||||||
|
},
|
||||||
|
"owner": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "manyToOne",
|
||||||
|
"target": "plugin::users-permissions.user",
|
||||||
|
"inversedBy": "contact_metas"
|
||||||
|
},
|
||||||
|
"favorite": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
|
"note": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/api/contact-meta/controllers/contact-meta.ts
Normal file
7
src/api/contact-meta/controllers/contact-meta.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* contact-meta controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi'
|
||||||
|
|
||||||
|
export default factories.createCoreController('api::contact-meta.contact-meta');
|
||||||
7
src/api/contact-meta/routes/contact-meta.ts
Normal file
7
src/api/contact-meta/routes/contact-meta.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* contact-meta router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::contact-meta.contact-meta');
|
||||||
7
src/api/contact-meta/services/contact-meta.ts
Normal file
7
src/api/contact-meta/services/contact-meta.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* contact-meta service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::contact-meta.contact-meta');
|
||||||
53
src/api/contact/content-types/contact/schema.json
Normal file
53
src/api/contact/content-types/contact/schema.json
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "contacts",
|
||||||
|
"info": {
|
||||||
|
"singularName": "contact",
|
||||||
|
"pluralName": "contacts",
|
||||||
|
"displayName": "Contact",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"owner": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "manyToOne",
|
||||||
|
"target": "plugin::users-permissions.user",
|
||||||
|
"inversedBy": "contacts"
|
||||||
|
},
|
||||||
|
"user": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "manyToOne",
|
||||||
|
"target": "plugin::users-permissions.user",
|
||||||
|
"inversedBy": "related_contacts"
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"pending",
|
||||||
|
"accepted",
|
||||||
|
"rejected",
|
||||||
|
"blocked",
|
||||||
|
"follow"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"message": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"requestedAt": {
|
||||||
|
"type": "datetime"
|
||||||
|
},
|
||||||
|
"respondedAt": {
|
||||||
|
"type": "datetime"
|
||||||
|
},
|
||||||
|
"metas": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::contact-meta.contact-meta",
|
||||||
|
"mappedBy": "contact"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
196
src/api/contact/controllers/contact.ts
Normal file
196
src/api/contact/controllers/contact.ts
Normal file
@@ -0,0 +1,196 @@
|
|||||||
|
/**
|
||||||
|
* contact controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from "@strapi/strapi";
|
||||||
|
|
||||||
|
export default factories.createCoreController(
|
||||||
|
"api::contact.contact",
|
||||||
|
({ strapi }) => ({
|
||||||
|
async find(ctx) {
|
||||||
|
// Log de la requête entrante
|
||||||
|
console.log("GET /contacts - Requête reçue:", {
|
||||||
|
query: ctx.query,
|
||||||
|
params: ctx.params,
|
||||||
|
user: ctx.state.user?.id || "anonymous",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Appel de la méthode parent
|
||||||
|
const result = await super.find(ctx);
|
||||||
|
|
||||||
|
// Log du résultat avant le return
|
||||||
|
console.log("GET /contacts - Résultat:", {
|
||||||
|
dataCount: result.data?.length || 0,
|
||||||
|
meta: result.meta,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
async findOne(ctx) {
|
||||||
|
// Log de la requête entrante
|
||||||
|
console.log("GET /contacts/:id - Requête reçue:", {
|
||||||
|
id: ctx.params.id,
|
||||||
|
query: ctx.query,
|
||||||
|
user: ctx.state.user?.id || "anonymous",
|
||||||
|
});
|
||||||
|
|
||||||
|
// Appel de la méthode parent
|
||||||
|
const result = await super.findOne(ctx);
|
||||||
|
|
||||||
|
// Log du résultat avant le return
|
||||||
|
console.log("GET /contacts/:id - Résultat:", {
|
||||||
|
found: !!result.data,
|
||||||
|
id: result.data?.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates or updates a contact.
|
||||||
|
*
|
||||||
|
* If a contact already exists with the same owner and user,
|
||||||
|
* only the state field is updated. Otherwise, a new contact is created.
|
||||||
|
*
|
||||||
|
* @param {Object} ctx - The request context.
|
||||||
|
* @returns {Object} The created or updated contact.
|
||||||
|
*/
|
||||||
|
async create(ctx) {
|
||||||
|
// Log de la requête entrante
|
||||||
|
console.log("POST /contacts - Requête reçue:", {
|
||||||
|
body: ctx.request.body,
|
||||||
|
user: ctx.state.user?.id || "anonymous",
|
||||||
|
});
|
||||||
|
|
||||||
|
try {
|
||||||
|
const { data } = ctx.request.body;
|
||||||
|
const { owner, user, state } = data;
|
||||||
|
|
||||||
|
// Vérifier si un contact existe déjà avec le même owner et user
|
||||||
|
const existingContact = await strapi
|
||||||
|
.documents("api::contact.contact")
|
||||||
|
.findFirst({
|
||||||
|
filters: {
|
||||||
|
owner: owner,
|
||||||
|
user: user,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingContact) {
|
||||||
|
// Mettre à jour uniquement le state
|
||||||
|
console.log(
|
||||||
|
"POST /contacts - Contact existant trouvé, mise à jour du state:",
|
||||||
|
{
|
||||||
|
documentId: existingContact.documentId,
|
||||||
|
oldState: existingContact.state,
|
||||||
|
newState: state,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const updatedContact = await strapi
|
||||||
|
.documents("api::contact.contact")
|
||||||
|
.update({
|
||||||
|
documentId: existingContact.documentId,
|
||||||
|
data: {
|
||||||
|
state: state,
|
||||||
|
respondedAt: new Date(),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return { data: updatedContact };
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sinon, créer un nouveau contact
|
||||||
|
console.log("POST /contacts - Création d'un nouveau contact");
|
||||||
|
const result = await super.create(ctx);
|
||||||
|
|
||||||
|
console.log("POST /contacts - Contact créé:", {
|
||||||
|
id: result.data?.id,
|
||||||
|
});
|
||||||
|
|
||||||
|
return result;
|
||||||
|
} catch (error) {
|
||||||
|
// Log de l'erreur
|
||||||
|
console.error("POST /contacts - Erreur:", {
|
||||||
|
error: error.message,
|
||||||
|
user: ctx.state.user?.id || "anonymous",
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes a contact by its ID.
|
||||||
|
*
|
||||||
|
* Logs the incoming request and attempts to find and delete the contact
|
||||||
|
* document. If the contact has associated meta documents owned by the user,
|
||||||
|
* those are deleted as well. If the contact is not found, a 404 response is returned.
|
||||||
|
* Logs any errors encountered during the process.
|
||||||
|
*
|
||||||
|
* @param {Object} ctx - The request context.
|
||||||
|
* @returns {Object} The response indicating the result of the delete operation.
|
||||||
|
*/
|
||||||
|
async delete(ctx) {
|
||||||
|
// Log de la requête entrante
|
||||||
|
console.log("DELETE /contacts/:id - Requête reçue:", {
|
||||||
|
id: ctx.params.id,
|
||||||
|
query: ctx.query,
|
||||||
|
user: ctx.state.user?.id || "anonymous",
|
||||||
|
});
|
||||||
|
const { id } = ctx.params;
|
||||||
|
|
||||||
|
try {
|
||||||
|
const result = await strapi
|
||||||
|
.documents("api::contact.contact")
|
||||||
|
.findFirst({
|
||||||
|
filters: {
|
||||||
|
$or: [
|
||||||
|
{
|
||||||
|
user: id,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
owner: id,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
populate: {
|
||||||
|
metas: {
|
||||||
|
populate: ["owner"],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!result) {
|
||||||
|
return ctx.notFound("Contact not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.metas) {
|
||||||
|
const metaDocumentId = result.metas.filter(
|
||||||
|
(s) => s.owner.id === ctx.state.user?.id
|
||||||
|
)[0]?.documentId;
|
||||||
|
if (metaDocumentId) {
|
||||||
|
await strapi.documents("api::contact-meta.contact-meta").delete({
|
||||||
|
documentId: metaDocumentId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
await strapi
|
||||||
|
.documents("api::contact.contact")
|
||||||
|
.delete({ documentId: result.documentId });
|
||||||
|
|
||||||
|
ctx.send({ message: "Contact deleted successfully" }, 200);
|
||||||
|
} catch (error) {
|
||||||
|
// Log de l'erreur
|
||||||
|
console.error("DELETE /contacts/:id - Erreur:", {
|
||||||
|
id: ctx.params.id,
|
||||||
|
error: error.message,
|
||||||
|
user: ctx.state.user?.id || "anonymous",
|
||||||
|
});
|
||||||
|
|
||||||
|
throw error;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
7
src/api/contact/routes/contact.ts
Normal file
7
src/api/contact/routes/contact.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* contact router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::contact.contact');
|
||||||
7
src/api/contact/services/contact.ts
Normal file
7
src/api/contact/services/contact.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* contact service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::contact.contact');
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "group_memberships",
|
||||||
|
"info": {
|
||||||
|
"singularName": "group-membership",
|
||||||
|
"pluralName": "group-memberships",
|
||||||
|
"displayName": "GroupMembership",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"user": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "manyToOne",
|
||||||
|
"target": "plugin::users-permissions.user",
|
||||||
|
"inversedBy": "group_memberships"
|
||||||
|
},
|
||||||
|
"group": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "manyToOne",
|
||||||
|
"target": "api::group.group",
|
||||||
|
"inversedBy": "memberships"
|
||||||
|
},
|
||||||
|
"role": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"member",
|
||||||
|
"admin",
|
||||||
|
"owner",
|
||||||
|
"follow"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/api/group-membership/controllers/group-membership.ts
Normal file
7
src/api/group-membership/controllers/group-membership.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* group-membership controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi'
|
||||||
|
|
||||||
|
export default factories.createCoreController('api::group-membership.group-membership');
|
||||||
7
src/api/group-membership/routes/group-membership.ts
Normal file
7
src/api/group-membership/routes/group-membership.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* group-membership router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::group-membership.group-membership');
|
||||||
7
src/api/group-membership/services/group-membership.ts
Normal file
7
src/api/group-membership/services/group-membership.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* group-membership service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::group-membership.group-membership');
|
||||||
76
src/api/group/content-types/group/schema.json
Normal file
76
src/api/group/content-types/group/schema.json
Normal file
@@ -0,0 +1,76 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "groups",
|
||||||
|
"info": {
|
||||||
|
"singularName": "group",
|
||||||
|
"pluralName": "groups",
|
||||||
|
"displayName": "Group",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"banner": {
|
||||||
|
"type": "media",
|
||||||
|
"multiple": false,
|
||||||
|
"required": false,
|
||||||
|
"allowedTypes": [
|
||||||
|
"images",
|
||||||
|
"files",
|
||||||
|
"videos",
|
||||||
|
"audios"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"tags": {
|
||||||
|
"displayName": "tags",
|
||||||
|
"type": "component",
|
||||||
|
"repeatable": true,
|
||||||
|
"component": "social.tags"
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"mixedChoir",
|
||||||
|
"womensChoir",
|
||||||
|
"mensChoir",
|
||||||
|
"childrensChoir"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"access": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"private",
|
||||||
|
"public",
|
||||||
|
"closed"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"memberships": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::group-membership.group-membership",
|
||||||
|
"mappedBy": "group"
|
||||||
|
},
|
||||||
|
"lastActivity": {
|
||||||
|
"type": "datetime"
|
||||||
|
},
|
||||||
|
"activityType": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"state": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"open",
|
||||||
|
"recruiting",
|
||||||
|
"audition"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
84
src/api/group/controllers/group.ts
Normal file
84
src/api/group/controllers/group.ts
Normal file
@@ -0,0 +1,84 @@
|
|||||||
|
// /src/api/group/controllers/group.ts
|
||||||
|
import { factories } from "@strapi/strapi";
|
||||||
|
|
||||||
|
export default factories.createCoreController(
|
||||||
|
"api::group.group",
|
||||||
|
({ strapi }) => ({
|
||||||
|
async create(ctx) {
|
||||||
|
// 1) Prépare le payload + upload banner
|
||||||
|
const body = ctx.request.body as any;
|
||||||
|
const data =
|
||||||
|
typeof body?.data === "string"
|
||||||
|
? JSON.parse(body.data)
|
||||||
|
: body?.data || {};
|
||||||
|
|
||||||
|
const bannerInput = (ctx.request.files as any)?.banner;
|
||||||
|
if (bannerInput) {
|
||||||
|
const file = Array.isArray(bannerInput) ? bannerInput[0] : bannerInput;
|
||||||
|
const uploaded = await strapi
|
||||||
|
.plugin("upload")
|
||||||
|
.service("upload")
|
||||||
|
.upload({
|
||||||
|
data: {
|
||||||
|
fileInfo: {
|
||||||
|
alternativeText: data?.name || "banner",
|
||||||
|
caption: "banner",
|
||||||
|
name: file.originalFilename || "banner",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
files: file,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (uploaded?.[0]?.id) {
|
||||||
|
data.banner = uploaded[0].id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 2) Crée le group via core controller
|
||||||
|
ctx.request.body = { data };
|
||||||
|
const response = await super.create(ctx); // { data: { id, attributes }, meta: {} }
|
||||||
|
|
||||||
|
// 3) Tente de créer le GroupMembership (owner) pour le user courant
|
||||||
|
const membershipMeta: {
|
||||||
|
success: boolean;
|
||||||
|
membershipId?: number;
|
||||||
|
error?: string;
|
||||||
|
} = { success: false };
|
||||||
|
|
||||||
|
try {
|
||||||
|
const userId = ctx.state.user?.id;
|
||||||
|
const groupId = response?.data?.id;
|
||||||
|
|
||||||
|
if (!userId) {
|
||||||
|
membershipMeta.error = "Unauthenticated user";
|
||||||
|
} else if (!groupId) {
|
||||||
|
membershipMeta.error = "Missing group id";
|
||||||
|
} else {
|
||||||
|
const membership = await strapi.entityService.create(
|
||||||
|
"api::group-membership.group-membership",
|
||||||
|
{
|
||||||
|
data: {
|
||||||
|
user: userId,
|
||||||
|
group: groupId,
|
||||||
|
role: "owner",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
);
|
||||||
|
membershipMeta.success = true;
|
||||||
|
membershipMeta.membershipId = membership?.id as number;
|
||||||
|
}
|
||||||
|
} catch (err: any) {
|
||||||
|
strapi.log.error(
|
||||||
|
"[group.create] Erreur création GroupMembership:",
|
||||||
|
err
|
||||||
|
);
|
||||||
|
membershipMeta.error = err?.message || "Unknown error";
|
||||||
|
}
|
||||||
|
|
||||||
|
// 4) Ajoute le résultat du membership dans la meta sans casser la création du group
|
||||||
|
response.meta = { ...(response.meta || {}), membership: membershipMeta };
|
||||||
|
|
||||||
|
return response;
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
7
src/api/group/routes/group.ts
Normal file
7
src/api/group/routes/group.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* group router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::group.group');
|
||||||
7
src/api/group/services/group.ts
Normal file
7
src/api/group/services/group.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* group service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::group.group');
|
||||||
45
src/api/invite/content-types/invite/schema.json
Normal file
45
src/api/invite/content-types/invite/schema.json
Normal file
@@ -0,0 +1,45 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "invites",
|
||||||
|
"info": {
|
||||||
|
"singularName": "invite",
|
||||||
|
"pluralName": "invites",
|
||||||
|
"displayName": "Invite",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"invitedUser": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToOne",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
},
|
||||||
|
"name": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"description": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"invitedBy": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToOne",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
},
|
||||||
|
"type": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"group",
|
||||||
|
"choral"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"members": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"invitedDate": {
|
||||||
|
"type": "datetime"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/api/invite/controllers/invite.ts
Normal file
7
src/api/invite/controllers/invite.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* invite controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi'
|
||||||
|
|
||||||
|
export default factories.createCoreController('api::invite.invite');
|
||||||
7
src/api/invite/routes/invite.ts
Normal file
7
src/api/invite/routes/invite.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* invite router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::invite.invite');
|
||||||
7
src/api/invite/services/invite.ts
Normal file
7
src/api/invite/services/invite.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* invite service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::invite.invite');
|
||||||
@@ -0,0 +1,50 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "post_ownerships",
|
||||||
|
"info": {
|
||||||
|
"singularName": "post-ownership",
|
||||||
|
"pluralName": "post-ownerships",
|
||||||
|
"displayName": "PostOwnership",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"author": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "manyToOne",
|
||||||
|
"target": "plugin::users-permissions.user",
|
||||||
|
"inversedBy": "post_ownerships"
|
||||||
|
},
|
||||||
|
"contextType": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"user",
|
||||||
|
"group",
|
||||||
|
"system"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"contextId": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"relation": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"owner",
|
||||||
|
"saved",
|
||||||
|
"hidden"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metas": {
|
||||||
|
"type": "json"
|
||||||
|
},
|
||||||
|
"post": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "manyToOne",
|
||||||
|
"target": "api::post.post",
|
||||||
|
"inversedBy": "post_ownerships"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/api/post-ownership/controllers/post-ownership.ts
Normal file
7
src/api/post-ownership/controllers/post-ownership.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* post-ownership controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi'
|
||||||
|
|
||||||
|
export default factories.createCoreController('api::post-ownership.post-ownership');
|
||||||
7
src/api/post-ownership/routes/post-ownership.ts
Normal file
7
src/api/post-ownership/routes/post-ownership.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* post-ownership router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::post-ownership.post-ownership');
|
||||||
7
src/api/post-ownership/services/post-ownership.ts
Normal file
7
src/api/post-ownership/services/post-ownership.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* post-ownership service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::post-ownership.post-ownership');
|
||||||
65
src/api/post/content-types/post/schema.json
Normal file
65
src/api/post/content-types/post/schema.json
Normal file
@@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "posts",
|
||||||
|
"info": {
|
||||||
|
"singularName": "post",
|
||||||
|
"pluralName": "posts",
|
||||||
|
"displayName": "Post",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"content": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"media": {
|
||||||
|
"type": "media",
|
||||||
|
"multiple": true,
|
||||||
|
"required": false,
|
||||||
|
"allowedTypes": ["images", "files", "videos", "audios"]
|
||||||
|
},
|
||||||
|
"likes": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
},
|
||||||
|
"category": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": ["photo", "video", "event"]
|
||||||
|
},
|
||||||
|
"comments": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::comment.comment"
|
||||||
|
},
|
||||||
|
"shares": {
|
||||||
|
"type": "integer"
|
||||||
|
},
|
||||||
|
"title": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"url": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"imageUrl": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"source": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"post_ownerships": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::post-ownership.post-ownership",
|
||||||
|
"mappedBy": "post"
|
||||||
|
},
|
||||||
|
"taggedContacts": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
583
src/api/post/controllers/post.ts
Normal file
583
src/api/post/controllers/post.ts
Normal file
@@ -0,0 +1,583 @@
|
|||||||
|
/**
|
||||||
|
* post controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from "@strapi/strapi";
|
||||||
|
|
||||||
|
export default factories.createCoreController(
|
||||||
|
"api::post.post",
|
||||||
|
({ strapi }) => ({
|
||||||
|
async create(ctx) {
|
||||||
|
const data = JSON.parse(ctx.request.body.data);
|
||||||
|
|
||||||
|
if (ctx.request.files.media) {
|
||||||
|
const files = Array.isArray(ctx.request.files.media)
|
||||||
|
? ctx.request.files.media[0]
|
||||||
|
: ctx.request.files.media;
|
||||||
|
const extension = files.originalFilename.match(/\.[0-9a-z]+$/i);
|
||||||
|
const payload = {
|
||||||
|
fileInfo: {
|
||||||
|
caption: "undefined",
|
||||||
|
alternativeText: data.name || "",
|
||||||
|
name: `${data.name}_media${extension}`,
|
||||||
|
},
|
||||||
|
};
|
||||||
|
const asset = await strapi.services["plugin::upload.upload"].upload({
|
||||||
|
data: payload,
|
||||||
|
files,
|
||||||
|
});
|
||||||
|
data.media = asset[0].id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Transformer taggedContacts en format de relation Strapi
|
||||||
|
if (data.taggedContacts && Array.isArray(data.taggedContacts)) {
|
||||||
|
data.taggedContacts = data.taggedContacts.map((id) => ({ id }));
|
||||||
|
}
|
||||||
|
|
||||||
|
delete data.author;
|
||||||
|
ctx.request.body = { data };
|
||||||
|
const result = await super.create(ctx);
|
||||||
|
|
||||||
|
// Créer le postOwnership associé
|
||||||
|
if (result.data) {
|
||||||
|
const userId = ctx.state.user?.id;
|
||||||
|
await strapi.db.query("api::post-ownership.post-ownership").create({
|
||||||
|
data: {
|
||||||
|
post: result.data.id,
|
||||||
|
author: userId,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: userId,
|
||||||
|
relation: "owner",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the feed for the authenticated user, including posts from friends, followed contacts,
|
||||||
|
* user's groups, friends' groups, and system posts. The feed is enriched with additional properties
|
||||||
|
* such as friend, contactFollow, member, and group.
|
||||||
|
*
|
||||||
|
* @param {Object} ctx - The Koa context object containing the request and response.
|
||||||
|
* @returns {Promise<void>} - Sends the enriched feed as the response.
|
||||||
|
*/
|
||||||
|
async feed(ctx) {
|
||||||
|
const userId = ctx.state.user?.id;
|
||||||
|
const { _limit = 20, _start = 0 } = ctx.query;
|
||||||
|
|
||||||
|
if (!userId) return ctx.badRequest("userId is required");
|
||||||
|
|
||||||
|
const queryParams = {
|
||||||
|
populate: {
|
||||||
|
post: {
|
||||||
|
populate: {
|
||||||
|
likes: true,
|
||||||
|
comments: {
|
||||||
|
populate: {
|
||||||
|
owner: {
|
||||||
|
populate: {
|
||||||
|
avatar: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
populate: {
|
||||||
|
avatar: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
media: true,
|
||||||
|
taggedContacts: {
|
||||||
|
populate: {
|
||||||
|
avatar: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
author: {
|
||||||
|
populate: {
|
||||||
|
avatar: true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
// populate context info if needed
|
||||||
|
},
|
||||||
|
sort: { createdAt: "desc" },
|
||||||
|
pagination: {
|
||||||
|
start: parseInt(String(_start)),
|
||||||
|
limit: parseInt(String(_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);
|
||||||
|
|
||||||
|
// Récupérer les contacts suivis (follow)
|
||||||
|
const blockedContacts = await strapi.db
|
||||||
|
.query("api::contact.contact")
|
||||||
|
.findMany({
|
||||||
|
where: {
|
||||||
|
owner: { id: parseInt(userId) },
|
||||||
|
state: "blocked",
|
||||||
|
},
|
||||||
|
populate: ["user"],
|
||||||
|
});
|
||||||
|
const blockedIds = blockedContacts.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 feed
|
||||||
|
const feed = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.findMany({
|
||||||
|
where: {
|
||||||
|
$or: [
|
||||||
|
// Posts réguliers (amis, follows, groupes, système, mes propres posts) - exclure les cachés
|
||||||
|
{
|
||||||
|
$and: [
|
||||||
|
{
|
||||||
|
$or: [
|
||||||
|
{ author: { id: friendIds } }, // Posts de mes amis
|
||||||
|
{ author: { id: followIds } }, // Posts des contacts que je suis
|
||||||
|
{ author: { id: parseInt(userId) }, relation: "owner" }, // Mes propres posts
|
||||||
|
{ contextType: "group", contextId: groupIds }, // Posts de mes groupes
|
||||||
|
{ contextType: "group", contextId: friendsGroupIds }, // Posts des groupes de mes amis
|
||||||
|
{ contextType: "system" }, // Posts système
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{ relation: { $ne: "hidden" } }, // exclure les posts masqués pour les posts réguliers
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Posts sauvés par l'utilisateur
|
||||||
|
{
|
||||||
|
contextType: "user",
|
||||||
|
contextId: parseInt(userId),
|
||||||
|
relation: "saved",
|
||||||
|
},
|
||||||
|
// Posts cachés par l'utilisateur
|
||||||
|
{
|
||||||
|
contextType: "user",
|
||||||
|
contextId: parseInt(userId),
|
||||||
|
relation: "hidden",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
...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️⃣ Enrichir le feed avec les propriétés friend, member, contactFollow et group
|
||||||
|
const enrichedFeed = feed.map((postOwnership) => {
|
||||||
|
const authorId = postOwnership.author?.id;
|
||||||
|
const contextType = postOwnership.contextType;
|
||||||
|
const contextId = postOwnership.contextId;
|
||||||
|
|
||||||
|
// 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 l'auteur est bloqué
|
||||||
|
const isBlocked = authorId ? blockedIds.includes(authorId) : false;
|
||||||
|
|
||||||
|
// Vérifier si je suis membre du groupe (seulement pour les posts 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;
|
||||||
|
|
||||||
|
return {
|
||||||
|
...postOwnership,
|
||||||
|
friend: isFriend,
|
||||||
|
contactFollow: isContactFollow,
|
||||||
|
member: isMember,
|
||||||
|
blocked: isBlocked,
|
||||||
|
...(group && { group }), // Ajouter group seulement s'il existe
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
const filteredFeedBlocked = enrichedFeed.filter((post) => !post.blocked);
|
||||||
|
|
||||||
|
// Trier par createdAt du post (le plus récent en premier)
|
||||||
|
const sortedFeed = filteredFeedBlocked.sort((a, b) => {
|
||||||
|
const dateA = a.post?.createdAt
|
||||||
|
? new Date(a.post.createdAt).getTime()
|
||||||
|
: 0;
|
||||||
|
const dateB = b.post?.createdAt
|
||||||
|
? new Date(b.post.createdAt).getTime()
|
||||||
|
: 0;
|
||||||
|
return dateB - dateA; // Ordre décroissant (plus récent en premier)
|
||||||
|
});
|
||||||
|
|
||||||
|
ctx.send(sortedFeed);
|
||||||
|
},
|
||||||
|
|
||||||
|
async likePost(ctx) {
|
||||||
|
const user = ctx.state.user; // Utilisateur actuellement connecté
|
||||||
|
if (!user) {
|
||||||
|
return ctx.unauthorized("You must be logged in to like a post.");
|
||||||
|
}
|
||||||
|
const postId = parseInt(String(ctx.params.id));
|
||||||
|
|
||||||
|
if (isNaN(postId)) {
|
||||||
|
return ctx.badRequest("Invalid post ID");
|
||||||
|
}
|
||||||
|
// Verify the post exists
|
||||||
|
const existingPost = await strapi.db.query("api::post.post").findOne({
|
||||||
|
where: {
|
||||||
|
id: postId,
|
||||||
|
},
|
||||||
|
populate: {
|
||||||
|
likes: true,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
if (!existingPost) {
|
||||||
|
return ctx.notFound("Post not found");
|
||||||
|
}
|
||||||
|
// Check if the user has already liked the post
|
||||||
|
const existingLike = existingPost.likes.find(
|
||||||
|
(like) => like.id === user.id
|
||||||
|
);
|
||||||
|
if (existingLike) {
|
||||||
|
await strapi.db.query("api::post.post").update({
|
||||||
|
where: { id: postId },
|
||||||
|
data: {
|
||||||
|
likes: {
|
||||||
|
disconnect: [{ id: user.id }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
return ctx.send({ message: "Post unliked successfully" });
|
||||||
|
}
|
||||||
|
// Update the postLikes field on the post entity
|
||||||
|
await strapi.db.query("api::post.post").update({
|
||||||
|
where: { id: postId },
|
||||||
|
data: {
|
||||||
|
likes: {
|
||||||
|
connect: [{ id: user.id }],
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
ctx.send({ message: "Post liked successfully" });
|
||||||
|
},
|
||||||
|
async savePost(ctx) {
|
||||||
|
console.log("🎯 savePost called with params:", ctx.params);
|
||||||
|
console.log("🎯 Request method:", ctx.request.method);
|
||||||
|
console.log("🎯 Request URL:", ctx.request.url);
|
||||||
|
|
||||||
|
const user = ctx.state.user;
|
||||||
|
if (!user) {
|
||||||
|
console.log("❌ User not authenticated");
|
||||||
|
return ctx.unauthorized("You must be logged in to save posts");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("✅ User authenticated:", user.id);
|
||||||
|
const postId = parseInt(String(ctx.params.id));
|
||||||
|
const authorId = parseInt(String(ctx.query.authorId));
|
||||||
|
|
||||||
|
if (isNaN(postId)) {
|
||||||
|
return ctx.badRequest("Invalid post ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the post exists
|
||||||
|
const post = await strapi.entityService.findOne("api::post.post", postId);
|
||||||
|
if (!post) {
|
||||||
|
return ctx.notFound("Post not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if post is already saved by this user
|
||||||
|
const existingSavedPost = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.findOne({
|
||||||
|
where: {
|
||||||
|
post: postId,
|
||||||
|
author: authorId,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: user.id,
|
||||||
|
relation: "saved",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingSavedPost) {
|
||||||
|
console.log("⚠️ Post already saved");
|
||||||
|
return ctx.badRequest("Post is already saved");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create postOwnership entry to mark post as saved
|
||||||
|
const savedPostOwnership = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.create({
|
||||||
|
data: {
|
||||||
|
post: postId,
|
||||||
|
author: authorId,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: user.id,
|
||||||
|
relation: "saved",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("✅ Post marked as saved:", savedPostOwnership);
|
||||||
|
|
||||||
|
// Get count of saved posts for this user
|
||||||
|
const savedPostsCount = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.count({
|
||||||
|
where: {
|
||||||
|
author: authorId,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: user.id,
|
||||||
|
relation: "saved",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return ctx.send({
|
||||||
|
message: "Post saved successfully",
|
||||||
|
savedPostsCount: savedPostsCount,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async removeSavedPost(ctx) {
|
||||||
|
console.log("🎯 removeSavedPost called with params:", ctx.params);
|
||||||
|
console.log("🎯 Request method:", ctx.request.method);
|
||||||
|
console.log("🎯 Request URL:", ctx.request.url);
|
||||||
|
|
||||||
|
const user = ctx.state.user;
|
||||||
|
if (!user) {
|
||||||
|
console.log("❌ User not authenticated");
|
||||||
|
return ctx.unauthorized("You must be logged in to remove saved posts");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("✅ User authenticated:", user.id);
|
||||||
|
const postId = parseInt(String(ctx.params.id));
|
||||||
|
|
||||||
|
if (isNaN(postId)) {
|
||||||
|
return ctx.badRequest("Invalid post ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the post exists
|
||||||
|
const post = await strapi.entityService.findOne("api::post.post", postId);
|
||||||
|
if (!post) {
|
||||||
|
return ctx.notFound("Post not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the saved post ownership entry
|
||||||
|
const savedPostOwnership = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.findOne({
|
||||||
|
where: {
|
||||||
|
post: postId,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: user.id,
|
||||||
|
relation: "saved",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!savedPostOwnership) {
|
||||||
|
console.log("⚠️ Post is not saved");
|
||||||
|
return ctx.badRequest("Post is not in your saved posts");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the saved post ownership entry
|
||||||
|
await strapi.db.query("api::post-ownership.post-ownership").delete({
|
||||||
|
where: { id: savedPostOwnership.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("✅ Post removed from saved posts successfully");
|
||||||
|
|
||||||
|
// Get updated count of saved posts for this user
|
||||||
|
const savedPostsCount = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.count({
|
||||||
|
where: {
|
||||||
|
author: user.id,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: user.id,
|
||||||
|
relation: "saved",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
return ctx.send({
|
||||||
|
message: "Post removed from saved posts successfully",
|
||||||
|
savedPostsCount: savedPostsCount,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async hidePost(ctx) {
|
||||||
|
console.log("🎯 hidePost called with params:", ctx.params);
|
||||||
|
console.log("🎯 Request method:", ctx.request.method);
|
||||||
|
console.log("🎯 Request URL:", ctx.request.url);
|
||||||
|
|
||||||
|
const user = ctx.state.user;
|
||||||
|
if (!user) {
|
||||||
|
console.log("❌ User not authenticated");
|
||||||
|
return ctx.unauthorized("You must be logged in to hide posts");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("✅ User authenticated:", user.id);
|
||||||
|
const postId = parseInt(String(ctx.params.id));
|
||||||
|
|
||||||
|
if (isNaN(postId)) {
|
||||||
|
return ctx.badRequest("Invalid post ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the post exists
|
||||||
|
const post = await strapi.entityService.findOne("api::post.post", postId);
|
||||||
|
if (!post) {
|
||||||
|
return ctx.notFound("Post not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if post is already hidden by this user
|
||||||
|
const existingHiddenPost = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.findOne({
|
||||||
|
where: {
|
||||||
|
post: postId,
|
||||||
|
author: user.id,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: user.id,
|
||||||
|
relation: "hidden",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (existingHiddenPost) {
|
||||||
|
console.log("⚠️ Post already hidden");
|
||||||
|
return ctx.badRequest("Post is already hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create postOwnership entry to mark post as hidden
|
||||||
|
const hiddenPostOwnership = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.create({
|
||||||
|
data: {
|
||||||
|
post: postId,
|
||||||
|
author: user.id,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: user.id,
|
||||||
|
relation: "hidden",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("✅ Post marked as hidden:", hiddenPostOwnership);
|
||||||
|
|
||||||
|
return ctx.send({
|
||||||
|
message: "Post hidden successfully",
|
||||||
|
hiddenPostId: postId,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
async removeHiddenPost(ctx) {
|
||||||
|
console.log("🎯 removeHiddenPost called with params:", ctx.params);
|
||||||
|
console.log("🎯 Request method:", ctx.request.method);
|
||||||
|
console.log("🎯 Request URL:", ctx.request.url);
|
||||||
|
|
||||||
|
const user = ctx.state.user;
|
||||||
|
if (!user) {
|
||||||
|
console.log("❌ User not authenticated");
|
||||||
|
return ctx.unauthorized("You must be logged in to unhide posts");
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log("✅ User authenticated:", user.id);
|
||||||
|
const postId = parseInt(String(ctx.params.id));
|
||||||
|
|
||||||
|
if (isNaN(postId)) {
|
||||||
|
return ctx.badRequest("Invalid post ID");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verify the post exists
|
||||||
|
const post = await strapi.entityService.findOne("api::post.post", postId);
|
||||||
|
if (!post) {
|
||||||
|
return ctx.notFound("Post not found");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Find the hidden post ownership entry
|
||||||
|
const hiddenPostOwnership = await strapi.db
|
||||||
|
.query("api::post-ownership.post-ownership")
|
||||||
|
.findOne({
|
||||||
|
where: {
|
||||||
|
post: postId,
|
||||||
|
author: user.id,
|
||||||
|
contextType: "user",
|
||||||
|
contextId: user.id,
|
||||||
|
relation: "hidden",
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
if (!hiddenPostOwnership) {
|
||||||
|
console.log("⚠️ Post is not hidden");
|
||||||
|
return ctx.badRequest("Post is not hidden");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Delete the hidden post ownership entry
|
||||||
|
await strapi.db.query("api::post-ownership.post-ownership").delete({
|
||||||
|
where: { id: hiddenPostOwnership.id },
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("✅ Post unhidden successfully");
|
||||||
|
|
||||||
|
return ctx.send({
|
||||||
|
message: "Post unhidden successfully",
|
||||||
|
unhiddenPostId: postId,
|
||||||
|
});
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
38
src/api/post/routes/custom.ts
Normal file
38
src/api/post/routes/custom.ts
Normal file
@@ -0,0 +1,38 @@
|
|||||||
|
/**
|
||||||
|
* Custom post routes
|
||||||
|
*/
|
||||||
|
|
||||||
|
export default {
|
||||||
|
routes: [
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
path: "/posts/:id/save",
|
||||||
|
handler: "post.savePost",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "DELETE",
|
||||||
|
path: "/posts/:id/save",
|
||||||
|
handler: "post.removeSavedPost",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "POST",
|
||||||
|
path: "/posts/:id/hide",
|
||||||
|
handler: "post.hidePost",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "DELETE",
|
||||||
|
path: "/posts/:id/hide",
|
||||||
|
handler: "post.removeHiddenPost",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "GET",
|
||||||
|
path: "/posts/feed",
|
||||||
|
handler: "post.feed",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: "PUT",
|
||||||
|
path: "/posts/:id/like",
|
||||||
|
handler: "post.likePost",
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
7
src/api/post/routes/post.ts
Normal file
7
src/api/post/routes/post.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* post router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from "@strapi/strapi";
|
||||||
|
|
||||||
|
export default factories.createCoreRouter("api::post.post");
|
||||||
7
src/api/post/services/post.ts
Normal file
7
src/api/post/services/post.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* post service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::post.post');
|
||||||
34
src/api/report/content-types/report/schema.json
Normal file
34
src/api/report/content-types/report/schema.json
Normal file
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
"kind": "collectionType",
|
||||||
|
"collectionName": "reports",
|
||||||
|
"info": {
|
||||||
|
"singularName": "report",
|
||||||
|
"pluralName": "reports",
|
||||||
|
"displayName": "report",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {
|
||||||
|
"draftAndPublish": false
|
||||||
|
},
|
||||||
|
"pluginOptions": {},
|
||||||
|
"attributes": {
|
||||||
|
"details": {
|
||||||
|
"type": "text"
|
||||||
|
},
|
||||||
|
"reason": {
|
||||||
|
"type": "enumeration",
|
||||||
|
"enum": [
|
||||||
|
"inappropriate",
|
||||||
|
"fraudulent",
|
||||||
|
"duplicate",
|
||||||
|
"expired",
|
||||||
|
"other"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"reporter": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToOne",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
7
src/api/report/controllers/report.ts
Normal file
7
src/api/report/controllers/report.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* report controller
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi'
|
||||||
|
|
||||||
|
export default factories.createCoreController('api::report.report');
|
||||||
7
src/api/report/routes/report.ts
Normal file
7
src/api/report/routes/report.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* report router
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreRouter('api::report.report');
|
||||||
7
src/api/report/services/report.ts
Normal file
7
src/api/report/services/report.ts
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
/**
|
||||||
|
* report service
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { factories } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export default factories.createCoreService('api::report.report');
|
||||||
35
src/components/address/full-address.json
Normal file
35
src/components/address/full-address.json
Normal file
@@ -0,0 +1,35 @@
|
|||||||
|
{
|
||||||
|
"collectionName": "components_address_full_addresses",
|
||||||
|
"info": {
|
||||||
|
"displayName": "FullAddress",
|
||||||
|
"icon": "pinMap",
|
||||||
|
"description": ""
|
||||||
|
},
|
||||||
|
"options": {},
|
||||||
|
"attributes": {
|
||||||
|
"freeaddress": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"housenumber": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"road": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"city": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"country": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"postcode": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"long": {
|
||||||
|
"type": "decimal"
|
||||||
|
},
|
||||||
|
"lat": {
|
||||||
|
"type": "decimal"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
13
src/components/social/tags.json
Normal file
13
src/components/social/tags.json
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
{
|
||||||
|
"collectionName": "components_social_tags",
|
||||||
|
"info": {
|
||||||
|
"displayName": "tags",
|
||||||
|
"icon": "emotionUnhappy"
|
||||||
|
},
|
||||||
|
"options": {},
|
||||||
|
"attributes": {
|
||||||
|
"tag": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -181,6 +181,49 @@
|
|||||||
"relation": "oneToMany",
|
"relation": "oneToMany",
|
||||||
"target": "api::announcement.announcement",
|
"target": "api::announcement.announcement",
|
||||||
"mappedBy": "author"
|
"mappedBy": "author"
|
||||||
|
},
|
||||||
|
"friends": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "plugin::users-permissions.user"
|
||||||
|
},
|
||||||
|
"group_memberships": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::group-membership.group-membership",
|
||||||
|
"mappedBy": "user"
|
||||||
|
},
|
||||||
|
"saved_posts": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::post.post"
|
||||||
|
},
|
||||||
|
"contacts": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::contact.contact",
|
||||||
|
"mappedBy": "owner"
|
||||||
|
},
|
||||||
|
"related_contacts": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::contact.contact",
|
||||||
|
"mappedBy": "user"
|
||||||
|
},
|
||||||
|
"contact_metas": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::contact-meta.contact-meta",
|
||||||
|
"mappedBy": "owner"
|
||||||
|
},
|
||||||
|
"phone": {
|
||||||
|
"type": "string"
|
||||||
|
},
|
||||||
|
"post_ownerships": {
|
||||||
|
"type": "relation",
|
||||||
|
"relation": "oneToMany",
|
||||||
|
"target": "api::post-ownership.post-ownership",
|
||||||
|
"mappedBy": "author"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
32
types/generated/components.d.ts
vendored
32
types/generated/components.d.ts
vendored
@@ -1,5 +1,35 @@
|
|||||||
import type { Schema, Struct } from '@strapi/strapi';
|
import type { Schema, Struct } from '@strapi/strapi';
|
||||||
|
|
||||||
|
export interface AddressFullAddress extends Struct.ComponentSchema {
|
||||||
|
collectionName: 'components_address_full_addresses';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'FullAddress';
|
||||||
|
icon: 'pinMap';
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
city: Schema.Attribute.String;
|
||||||
|
country: Schema.Attribute.String;
|
||||||
|
freeaddress: Schema.Attribute.String;
|
||||||
|
housenumber: Schema.Attribute.String;
|
||||||
|
lat: Schema.Attribute.Decimal;
|
||||||
|
long: Schema.Attribute.Decimal;
|
||||||
|
postcode: Schema.Attribute.String;
|
||||||
|
road: Schema.Attribute.String;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface SocialTags extends Struct.ComponentSchema {
|
||||||
|
collectionName: 'components_social_tags';
|
||||||
|
info: {
|
||||||
|
displayName: 'tags';
|
||||||
|
icon: 'emotionUnhappy';
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
tag: Schema.Attribute.String;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface UserPermissions extends Struct.ComponentSchema {
|
export interface UserPermissions extends Struct.ComponentSchema {
|
||||||
collectionName: 'components_user_permissions';
|
collectionName: 'components_user_permissions';
|
||||||
info: {
|
info: {
|
||||||
@@ -19,6 +49,8 @@ export interface UserPermissions extends Struct.ComponentSchema {
|
|||||||
declare module '@strapi/strapi' {
|
declare module '@strapi/strapi' {
|
||||||
export module Public {
|
export module Public {
|
||||||
export interface ComponentSchemas {
|
export interface ComponentSchemas {
|
||||||
|
'address.full-address': AddressFullAddress;
|
||||||
|
'social.tags': SocialTags;
|
||||||
'user.permissions': UserPermissions;
|
'user.permissions': UserPermissions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
432
types/generated/contentTypes.d.ts
vendored
432
types/generated/contentTypes.d.ts
vendored
@@ -369,6 +369,48 @@ export interface AdminUser extends Struct.CollectionTypeSchema {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiAdAd extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'ads';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'Ad';
|
||||||
|
pluralName: 'ads';
|
||||||
|
singularName: 'ad';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
applies: Schema.Attribute.Integer;
|
||||||
|
author: Schema.Attribute.Relation<
|
||||||
|
'oneToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
category: Schema.Attribute.Enumeration<
|
||||||
|
['hire', 'equipment', 'management', 'sheetmusic', 'local']
|
||||||
|
>;
|
||||||
|
contactemail: Schema.Attribute.String;
|
||||||
|
contactname: Schema.Attribute.String;
|
||||||
|
contactphone: Schema.Attribute.String;
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
description: Schema.Attribute.Text;
|
||||||
|
featured: Schema.Attribute.Boolean;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<'oneToMany', 'api::ad.ad'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
location: Schema.Attribute.Component<'address.full-address', false>;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
title: Schema.Attribute.String;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
validUntil: Schema.Attribute.Date;
|
||||||
|
views: Schema.Attribute.Integer;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface ApiAnnouncementAnnouncement
|
export interface ApiAnnouncementAnnouncement
|
||||||
extends Struct.CollectionTypeSchema {
|
extends Struct.CollectionTypeSchema {
|
||||||
collectionName: 'announcements';
|
collectionName: 'announcements';
|
||||||
@@ -678,6 +720,124 @@ export interface ApiChoralChoral extends Struct.CollectionTypeSchema {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiCommentComment extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'comments';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'Comment';
|
||||||
|
pluralName: 'comments';
|
||||||
|
singularName: 'comment';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
content: Schema.Attribute.String;
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
likes: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::comment.comment'
|
||||||
|
> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
owner: Schema.Attribute.Relation<
|
||||||
|
'oneToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
replies: Schema.Attribute.Relation<'oneToMany', 'api::comment.comment'>;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiContactMetaContactMeta extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'contact_metas';
|
||||||
|
info: {
|
||||||
|
displayName: 'ContactMeta';
|
||||||
|
pluralName: 'contact-metas';
|
||||||
|
singularName: 'contact-meta';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
contact: Schema.Attribute.Relation<'manyToOne', 'api::contact.contact'>;
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
favorite: Schema.Attribute.Boolean;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::contact-meta.contact-meta'
|
||||||
|
> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
note: Schema.Attribute.String;
|
||||||
|
owner: Schema.Attribute.Relation<
|
||||||
|
'manyToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiContactContact extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'contacts';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'Contact';
|
||||||
|
pluralName: 'contacts';
|
||||||
|
singularName: 'contact';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::contact.contact'
|
||||||
|
> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
message: Schema.Attribute.Text;
|
||||||
|
metas: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::contact-meta.contact-meta'
|
||||||
|
>;
|
||||||
|
owner: Schema.Attribute.Relation<
|
||||||
|
'manyToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
requestedAt: Schema.Attribute.DateTime;
|
||||||
|
respondedAt: Schema.Attribute.DateTime;
|
||||||
|
state: Schema.Attribute.Enumeration<
|
||||||
|
['pending', 'accepted', 'rejected', 'blocked', 'follow']
|
||||||
|
>;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
user: Schema.Attribute.Relation<
|
||||||
|
'manyToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface ApiConversationConversation
|
export interface ApiConversationConversation
|
||||||
extends Struct.CollectionTypeSchema {
|
extends Struct.CollectionTypeSchema {
|
||||||
collectionName: 'conversations';
|
collectionName: 'conversations';
|
||||||
@@ -835,6 +995,122 @@ export interface ApiEventEvent extends Struct.CollectionTypeSchema {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiGroupMembershipGroupMembership
|
||||||
|
extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'group_memberships';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'GroupMembership';
|
||||||
|
pluralName: 'group-memberships';
|
||||||
|
singularName: 'group-membership';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
group: Schema.Attribute.Relation<'manyToOne', 'api::group.group'>;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::group-membership.group-membership'
|
||||||
|
> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
role: Schema.Attribute.Enumeration<['member', 'admin', 'owner', 'follow']>;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
user: Schema.Attribute.Relation<
|
||||||
|
'manyToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiGroupGroup extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'groups';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'Group';
|
||||||
|
pluralName: 'groups';
|
||||||
|
singularName: 'group';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
access: Schema.Attribute.Enumeration<['private', 'public', 'closed']>;
|
||||||
|
activityType: Schema.Attribute.String;
|
||||||
|
banner: Schema.Attribute.Media<'images' | 'files' | 'videos' | 'audios'>;
|
||||||
|
category: Schema.Attribute.Enumeration<
|
||||||
|
['mixedChoir', 'womensChoir', 'mensChoir', 'childrensChoir']
|
||||||
|
>;
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
description: Schema.Attribute.Text;
|
||||||
|
lastActivity: Schema.Attribute.DateTime;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<'oneToMany', 'api::group.group'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
memberships: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::group-membership.group-membership'
|
||||||
|
>;
|
||||||
|
name: Schema.Attribute.String;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
state: Schema.Attribute.Enumeration<['open', 'recruiting', 'audition']>;
|
||||||
|
tags: Schema.Attribute.Component<'social.tags', true>;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiInviteInvite extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'invites';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'Invite';
|
||||||
|
pluralName: 'invites';
|
||||||
|
singularName: 'invite';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
description: Schema.Attribute.Text;
|
||||||
|
invitedBy: Schema.Attribute.Relation<
|
||||||
|
'oneToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
invitedDate: Schema.Attribute.DateTime;
|
||||||
|
invitedUser: Schema.Attribute.Relation<
|
||||||
|
'oneToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::invite.invite'
|
||||||
|
> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
members: Schema.Attribute.Integer;
|
||||||
|
name: Schema.Attribute.String;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
type: Schema.Attribute.Enumeration<['group', 'choral']>;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface ApiMessageMessage extends Struct.CollectionTypeSchema {
|
export interface ApiMessageMessage extends Struct.CollectionTypeSchema {
|
||||||
collectionName: 'messages';
|
collectionName: 'messages';
|
||||||
info: {
|
info: {
|
||||||
@@ -904,6 +1180,129 @@ export interface ApiPermissionsTemplatePermissionsTemplate
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface ApiPostOwnershipPostOwnership
|
||||||
|
extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'post_ownerships';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'PostOwnership';
|
||||||
|
pluralName: 'post-ownerships';
|
||||||
|
singularName: 'post-ownership';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
author: Schema.Attribute.Relation<
|
||||||
|
'manyToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
contextId: Schema.Attribute.Integer;
|
||||||
|
contextType: Schema.Attribute.Enumeration<['user', 'group', 'system']>;
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::post-ownership.post-ownership'
|
||||||
|
> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
metas: Schema.Attribute.JSON;
|
||||||
|
post: Schema.Attribute.Relation<'manyToOne', 'api::post.post'>;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
relation: Schema.Attribute.Enumeration<['owner', 'saved', 'hidden']>;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiPostPost extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'posts';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'Post';
|
||||||
|
pluralName: 'posts';
|
||||||
|
singularName: 'post';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
category: Schema.Attribute.Enumeration<['photo', 'video', 'event']>;
|
||||||
|
comments: Schema.Attribute.Relation<'oneToMany', 'api::comment.comment'>;
|
||||||
|
content: Schema.Attribute.Text;
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
imageUrl: Schema.Attribute.String;
|
||||||
|
likes: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<'oneToMany', 'api::post.post'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
media: Schema.Attribute.Media<
|
||||||
|
'images' | 'files' | 'videos' | 'audios',
|
||||||
|
true
|
||||||
|
>;
|
||||||
|
post_ownerships: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::post-ownership.post-ownership'
|
||||||
|
>;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
shares: Schema.Attribute.Integer;
|
||||||
|
source: Schema.Attribute.String;
|
||||||
|
taggedContacts: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
title: Schema.Attribute.String;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
url: Schema.Attribute.String;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ApiReportReport extends Struct.CollectionTypeSchema {
|
||||||
|
collectionName: 'reports';
|
||||||
|
info: {
|
||||||
|
description: '';
|
||||||
|
displayName: 'report';
|
||||||
|
pluralName: 'reports';
|
||||||
|
singularName: 'report';
|
||||||
|
};
|
||||||
|
options: {
|
||||||
|
draftAndPublish: false;
|
||||||
|
};
|
||||||
|
attributes: {
|
||||||
|
createdAt: Schema.Attribute.DateTime;
|
||||||
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
details: Schema.Attribute.Text;
|
||||||
|
locale: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
|
localizations: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::report.report'
|
||||||
|
> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
reason: Schema.Attribute.Enumeration<
|
||||||
|
['inappropriate', 'fraudulent', 'duplicate', 'expired', 'other']
|
||||||
|
>;
|
||||||
|
reporter: Schema.Attribute.Relation<
|
||||||
|
'oneToOne',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
|
Schema.Attribute.Private;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
export interface PluginContentReleasesRelease
|
export interface PluginContentReleasesRelease
|
||||||
extends Struct.CollectionTypeSchema {
|
extends Struct.CollectionTypeSchema {
|
||||||
collectionName: 'strapi_releases';
|
collectionName: 'strapi_releases';
|
||||||
@@ -1385,6 +1784,11 @@ export interface PluginUsersPermissionsUser
|
|||||||
chorals: Schema.Attribute.Relation<'manyToMany', 'api::choral.choral'>;
|
chorals: Schema.Attribute.Relation<'manyToMany', 'api::choral.choral'>;
|
||||||
confirmationToken: Schema.Attribute.String & Schema.Attribute.Private;
|
confirmationToken: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
confirmed: Schema.Attribute.Boolean & Schema.Attribute.DefaultTo<false>;
|
confirmed: Schema.Attribute.Boolean & Schema.Attribute.DefaultTo<false>;
|
||||||
|
contact_metas: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::contact-meta.contact-meta'
|
||||||
|
>;
|
||||||
|
contacts: Schema.Attribute.Relation<'oneToMany', 'api::contact.contact'>;
|
||||||
createdAt: Schema.Attribute.DateTime;
|
createdAt: Schema.Attribute.DateTime;
|
||||||
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
createdBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
Schema.Attribute.Private;
|
Schema.Attribute.Private;
|
||||||
@@ -1394,7 +1798,15 @@ export interface PluginUsersPermissionsUser
|
|||||||
Schema.Attribute.SetMinMaxLength<{
|
Schema.Attribute.SetMinMaxLength<{
|
||||||
minLength: 6;
|
minLength: 6;
|
||||||
}>;
|
}>;
|
||||||
|
friends: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'plugin::users-permissions.user'
|
||||||
|
>;
|
||||||
gender: Schema.Attribute.Enumeration<['men', 'women', 'none']>;
|
gender: Schema.Attribute.Enumeration<['men', 'women', 'none']>;
|
||||||
|
group_memberships: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::group-membership.group-membership'
|
||||||
|
>;
|
||||||
job: Schema.Attribute.Enumeration<
|
job: Schema.Attribute.Enumeration<
|
||||||
['choir_director', 'choir_addict', 'choir_master', 'choir_singer', 'none']
|
['choir_director', 'choir_addict', 'choir_master', 'choir_singer', 'none']
|
||||||
>;
|
>;
|
||||||
@@ -1414,13 +1826,23 @@ export interface PluginUsersPermissionsUser
|
|||||||
Schema.Attribute.SetMinMaxLength<{
|
Schema.Attribute.SetMinMaxLength<{
|
||||||
minLength: 6;
|
minLength: 6;
|
||||||
}>;
|
}>;
|
||||||
|
phone: Schema.Attribute.String;
|
||||||
|
post_ownerships: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::post-ownership.post-ownership'
|
||||||
|
>;
|
||||||
provider: Schema.Attribute.String;
|
provider: Schema.Attribute.String;
|
||||||
publishedAt: Schema.Attribute.DateTime;
|
publishedAt: Schema.Attribute.DateTime;
|
||||||
|
related_contacts: Schema.Attribute.Relation<
|
||||||
|
'oneToMany',
|
||||||
|
'api::contact.contact'
|
||||||
|
>;
|
||||||
resetPasswordToken: Schema.Attribute.String & Schema.Attribute.Private;
|
resetPasswordToken: Schema.Attribute.String & Schema.Attribute.Private;
|
||||||
role: Schema.Attribute.Relation<
|
role: Schema.Attribute.Relation<
|
||||||
'manyToOne',
|
'manyToOne',
|
||||||
'plugin::users-permissions.role'
|
'plugin::users-permissions.role'
|
||||||
>;
|
>;
|
||||||
|
saved_posts: Schema.Attribute.Relation<'oneToMany', 'api::post.post'>;
|
||||||
surname: Schema.Attribute.String;
|
surname: Schema.Attribute.String;
|
||||||
updatedAt: Schema.Attribute.DateTime;
|
updatedAt: Schema.Attribute.DateTime;
|
||||||
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
updatedBy: Schema.Attribute.Relation<'oneToOne', 'admin::user'> &
|
||||||
@@ -1447,6 +1869,7 @@ declare module '@strapi/strapi' {
|
|||||||
'admin::transfer-token': AdminTransferToken;
|
'admin::transfer-token': AdminTransferToken;
|
||||||
'admin::transfer-token-permission': AdminTransferTokenPermission;
|
'admin::transfer-token-permission': AdminTransferTokenPermission;
|
||||||
'admin::user': AdminUser;
|
'admin::user': AdminUser;
|
||||||
|
'api::ad.ad': ApiAdAd;
|
||||||
'api::announcement.announcement': ApiAnnouncementAnnouncement;
|
'api::announcement.announcement': ApiAnnouncementAnnouncement;
|
||||||
'api::board-card.board-card': ApiBoardCardBoardCard;
|
'api::board-card.board-card': ApiBoardCardBoardCard;
|
||||||
'api::board-list.board-list': ApiBoardListBoardList;
|
'api::board-list.board-list': ApiBoardListBoardList;
|
||||||
@@ -1455,12 +1878,21 @@ declare module '@strapi/strapi' {
|
|||||||
'api::choral-membership.choral-membership': ApiChoralMembershipChoralMembership;
|
'api::choral-membership.choral-membership': ApiChoralMembershipChoralMembership;
|
||||||
'api::choral-permission.choral-permission': ApiChoralPermissionChoralPermission;
|
'api::choral-permission.choral-permission': ApiChoralPermissionChoralPermission;
|
||||||
'api::choral.choral': ApiChoralChoral;
|
'api::choral.choral': ApiChoralChoral;
|
||||||
|
'api::comment.comment': ApiCommentComment;
|
||||||
|
'api::contact-meta.contact-meta': ApiContactMetaContactMeta;
|
||||||
|
'api::contact.contact': ApiContactContact;
|
||||||
'api::conversation.conversation': ApiConversationConversation;
|
'api::conversation.conversation': ApiConversationConversation;
|
||||||
'api::direct-message.direct-message': ApiDirectMessageDirectMessage;
|
'api::direct-message.direct-message': ApiDirectMessageDirectMessage;
|
||||||
'api::event-other.event-other': ApiEventOtherEventOther;
|
'api::event-other.event-other': ApiEventOtherEventOther;
|
||||||
'api::event.event': ApiEventEvent;
|
'api::event.event': ApiEventEvent;
|
||||||
|
'api::group-membership.group-membership': ApiGroupMembershipGroupMembership;
|
||||||
|
'api::group.group': ApiGroupGroup;
|
||||||
|
'api::invite.invite': ApiInviteInvite;
|
||||||
'api::message.message': ApiMessageMessage;
|
'api::message.message': ApiMessageMessage;
|
||||||
'api::permissions-template.permissions-template': ApiPermissionsTemplatePermissionsTemplate;
|
'api::permissions-template.permissions-template': ApiPermissionsTemplatePermissionsTemplate;
|
||||||
|
'api::post-ownership.post-ownership': ApiPostOwnershipPostOwnership;
|
||||||
|
'api::post.post': ApiPostPost;
|
||||||
|
'api::report.report': ApiReportReport;
|
||||||
'plugin::content-releases.release': PluginContentReleasesRelease;
|
'plugin::content-releases.release': PluginContentReleasesRelease;
|
||||||
'plugin::content-releases.release-action': PluginContentReleasesReleaseAction;
|
'plugin::content-releases.release-action': PluginContentReleasesReleaseAction;
|
||||||
'plugin::i18n.locale': PluginI18NLocale;
|
'plugin::i18n.locale': PluginI18NLocale;
|
||||||
|
|||||||
Reference in New Issue
Block a user