Skip to content

Commit fb08ac3

Browse files
authored
Merge pull request #97 from RustyRory/feat/96-collection-matches
feat(backend): Fixes #96 - Collection Matches
2 parents 6095da0 + a24c8e2 commit fb08ac3

6 files changed

Lines changed: 163 additions & 1 deletion

File tree

app/backend/src/app.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import mediasRoutes from './routes/medias.js';
2424
import partnersRoutes from './routes/partners.js';
2525
import championshipsRoutes from './routes/championships.js';
2626
import standingsRoutes from './routes/standings.js';
27+
import matchesRoutes from './routes/matches.js';
2728

2829
// Utiliser les routes
2930
app.use('/api/users', usersRoutes);
@@ -37,6 +38,7 @@ app.use('/api/medias', mediasRoutes);
3738
app.use('/api/partners', partnersRoutes);
3839
app.use('/api/championships', championshipsRoutes);
3940
app.use('/api/standings', standingsRoutes);
41+
app.use('/api/matches', matchesRoutes);
4042

4143
// Exporter l'application
4244
export default app;
Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
import Match from '../models/Match.js';
2+
3+
// Liste des matchs (par championnat)
4+
export const getMatches = async (req, res) => {
5+
try {
6+
const filter = {};
7+
8+
if (req.query.championshipId) {
9+
filter.championshipId = req.query.championshipId;
10+
}
11+
12+
const matches = await Match.find(filter).populate('championshipId').sort({ date: 1 });
13+
14+
res.json(matches);
15+
} catch (error) {
16+
res.status(500).json({ message: error.message });
17+
}
18+
};
19+
20+
// Match par ID
21+
export const getMatchById = async (req, res) => {
22+
try {
23+
const match = await Match.findById(req.params.id).populate('championshipId');
24+
25+
if (!match) {
26+
return res.status(404).json({ message: 'Match non trouvé' });
27+
}
28+
29+
res.json(match);
30+
} catch (error) {
31+
res.status(500).json({ message: error.message });
32+
}
33+
};
34+
35+
// Création (import FFVB ou manuel)
36+
export const createMatch = async (req, res) => {
37+
try {
38+
const match = await Match.create(req.body);
39+
res.status(201).json(match);
40+
} catch (error) {
41+
res.status(400).json({ message: error.message });
42+
}
43+
};
44+
45+
// Mise à jour (score, statut, etc.)
46+
export const updateMatch = async (req, res) => {
47+
try {
48+
const match = await Match.findByIdAndUpdate(req.params.id, req.body, {
49+
new: true,
50+
runValidators: true,
51+
});
52+
53+
if (!match) {
54+
return res.status(404).json({ message: 'Match non trouvé' });
55+
}
56+
57+
res.json(match);
58+
} catch (error) {
59+
res.status(400).json({ message: error.message });
60+
}
61+
};
62+
63+
// Suppression
64+
export const deleteMatch = async (req, res) => {
65+
try {
66+
const match = await Match.findByIdAndDelete(req.params.id);
67+
68+
if (!match) {
69+
return res.status(404).json({ message: 'Match non trouvé' });
70+
}
71+
72+
res.json({ message: 'Match supprimé' });
73+
} catch (error) {
74+
res.status(500).json({ message: error.message });
75+
}
76+
};

app/backend/src/models/Match.js

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
import mongoose from 'mongoose';
2+
3+
const setDetailSchema = new mongoose.Schema(
4+
{
5+
setNumber: {
6+
type: Number,
7+
required: true,
8+
min: 1,
9+
},
10+
scoreFor: {
11+
type: Number,
12+
required: true,
13+
min: 0,
14+
},
15+
scoreAgainst: {
16+
type: Number,
17+
required: true,
18+
min: 0,
19+
},
20+
},
21+
{ _id: false },
22+
);
23+
24+
const matchSchema = new mongoose.Schema(
25+
{
26+
championshipId: {
27+
type: mongoose.Schema.Types.ObjectId,
28+
ref: 'ChampionshipFFVB',
29+
required: true,
30+
},
31+
opponentName: {
32+
type: String,
33+
required: true,
34+
trim: true,
35+
},
36+
date: {
37+
type: Date,
38+
required: true,
39+
},
40+
address: {
41+
type: String,
42+
default: '',
43+
trim: true,
44+
},
45+
homeAway: {
46+
type: String,
47+
enum: ['home', 'away'],
48+
required: true,
49+
},
50+
status: {
51+
type: String,
52+
enum: ['scheduled', 'played'],
53+
default: 'scheduled',
54+
},
55+
scoreFor: {
56+
type: Number,
57+
min: 0,
58+
default: null,
59+
},
60+
scoreAgainst: {
61+
type: Number,
62+
min: 0,
63+
default: null,
64+
},
65+
setsDetail: [setDetailSchema],
66+
},
67+
{
68+
timestamps: true,
69+
},
70+
);
71+
72+
export default mongoose.model('Match', matchSchema);

app/backend/src/models/Member.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ const memberSchema = new mongoose.Schema(
1616
type: [
1717
{
1818
type: String,
19-
enum: ['owner', 'staff', 'volunteer', 'player', 'coach', 'other'],
19+
enum: ['owner', 'staff', 'volunteer', 'referee', 'player', 'coach', 'other'],
2020
},
2121
],
2222
required: true,

app/backend/src/routes/matches.js

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import express from 'express';
2+
import { getMatches, getMatchById, createMatch, updateMatch, deleteMatch } from '../controllers/matchesController.js';
3+
4+
const router = express.Router();
5+
6+
router.get('/', getMatches);
7+
router.get('/:id', getMatchById);
8+
router.post('/', createMatch);
9+
router.put('/:id', updateMatch);
10+
router.delete('/:id', deleteMatch);
11+
12+
export default router;

docs/projet/scraping.md

Whitespace-only changes.

0 commit comments

Comments
 (0)