feat(tactics): add functionality for managing tactic plans in official tournaments
All checks were successful
Deploy tt-tagebuch / deploy (push) Successful in 55s

- Implemented routes for listing, saving, updating, and deleting tactic plans in officialTournamentRoutes.js.
- Created OfficialTournamentTacticPlan model to handle tactic plan data.
- Developed OfficialTournamentService methods for tactic plan operations including validation and error handling.
- Enhanced OfficialTournaments.vue to include a new tactics tab with UI for managing tactic plans.
- Added TacticBoard component for visualizing and editing tactic paths.
- Updated server.js to synchronize the new tactic plan model.
This commit is contained in:
Torsten Schulz (local)
2026-08-14 13:15:26 +02:00
parent 3320884cef
commit f59c7391b8
8 changed files with 519 additions and 16 deletions

View File

@@ -0,0 +1,23 @@
import { DataTypes } from 'sequelize';
import sequelize from '../database.js';
const OfficialTournamentTacticPlan = sequelize.define('OfficialTournamentTacticPlan', {
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
tournamentId: { type: DataTypes.INTEGER, allowNull: false },
competitionId: { type: DataTypes.INTEGER, allowNull: false },
memberId: { type: DataTypes.INTEGER, allowNull: false },
round: { type: DataTypes.STRING, allowNull: true },
opponentName: { type: DataTypes.STRING, allowNull: true },
ownStrengths: { type: DataTypes.TEXT, allowNull: true },
ownWeaknesses: { type: DataTypes.TEXT, allowNull: true },
opponentStrengths: { type: DataTypes.TEXT, allowNull: true },
opponentWeaknesses: { type: DataTypes.TEXT, allowNull: true },
drawingData: { type: DataTypes.TEXT('medium'), allowNull: true },
}, {
tableName: 'official_tournament_tactic_plans',
timestamps: true,
underscored: true,
indexes: [{ fields: ['tournament_id'] }, { fields: ['competition_id', 'member_id'] }],
});
export default OfficialTournamentTacticPlan;

View File

@@ -41,6 +41,7 @@ import UserToken from './UserToken.js';
import OfficialTournament from './OfficialTournament.js';
import OfficialCompetition from './OfficialCompetition.js';
import OfficialCompetitionMember from './OfficialCompetitionMember.js';
import OfficialTournamentTacticPlan from './OfficialTournamentTacticPlan.js';
import MyTischtennis from './MyTischtennis.js';
import MyTischtennisUpdateHistory from './MyTischtennisUpdateHistory.js';
import MyTischtennisFetchLog from './MyTischtennisFetchLog.js';
@@ -108,6 +109,10 @@ OfficialTournament.hasMany(OfficialCompetitionMember, { foreignKey: 'tournamentI
OfficialCompetitionMember.belongsTo(OfficialTournament, { foreignKey: 'tournamentId', as: 'tournament' });
Member.hasMany(OfficialCompetitionMember, { foreignKey: 'memberId', as: 'officialCompetitionEntries' });
OfficialCompetitionMember.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
OfficialTournament.hasMany(OfficialTournamentTacticPlan, { foreignKey: 'tournamentId', as: 'tacticPlans' });
OfficialTournamentTacticPlan.belongsTo(OfficialTournament, { foreignKey: 'tournamentId', as: 'tournament' });
OfficialTournamentTacticPlan.belongsTo(OfficialCompetition, { foreignKey: 'competitionId', as: 'competition' });
OfficialTournamentTacticPlan.belongsTo(Member, { foreignKey: 'memberId', as: 'member' });
User.hasMany(Log, { foreignKey: 'userId' });
Log.belongsTo(User, { foreignKey: 'userId' });
@@ -665,6 +670,7 @@ export {
OfficialTournament,
OfficialCompetition,
OfficialCompetitionMember,
OfficialTournamentTacticPlan,
MyTischtennis,
MyTischtennisUpdateHistory,
MyTischtennisFetchLog,