FEAT: Aprimora Templates Whatsapp
All checks were successful
Deploy Dev / deploy (push) Successful in 3s
All checks were successful
Deploy Dev / deploy (push) Successful in 3s
This commit is contained in:
parent
3ae6b7e978
commit
22e4742384
@ -65,12 +65,27 @@ export class WhatsappController {
|
||||
}
|
||||
|
||||
@Post('templates')
|
||||
async saveTemplate(@Body() body: { name: string; content: string }) {
|
||||
return this.whatsappService.saveTemplate(body.name, body.content);
|
||||
async saveTemplate(@Body() body: { name: string; content: string; areaId?: number | null; requestedByRole?: string }) {
|
||||
return this.whatsappService.saveTemplate(body.name, body.content, body.areaId, body.requestedByRole);
|
||||
}
|
||||
|
||||
@Post('templates/update/:id')
|
||||
async updateTemplate(@Param('id') id: string, @Body() body: { name: string; content: string }) {
|
||||
return this.whatsappService.updateTemplate(Number(id), body.name, body.content);
|
||||
async updateTemplate(@Param('id') id: string, @Body() body: { name: string; content: string; areaId?: number | null }) {
|
||||
return this.whatsappService.updateTemplate(Number(id), body.name, body.content, body.areaId);
|
||||
}
|
||||
|
||||
@Post('templates/approve-admin/:id')
|
||||
async approveTemplateByAdmin(@Param('id') id: string) {
|
||||
return this.whatsappService.approveTemplateByAdmin(Number(id));
|
||||
}
|
||||
|
||||
@Post('templates/reject-admin/:id')
|
||||
async rejectTemplateByAdmin(@Param('id') id: string) {
|
||||
return this.whatsappService.rejectTemplateByAdmin(Number(id));
|
||||
}
|
||||
|
||||
@Delete('templates/:id')
|
||||
async deleteTemplate(@Param('id') id: string) {
|
||||
return this.whatsappService.deleteTemplate(Number(id));
|
||||
}
|
||||
}
|
||||
|
||||
@ -30,10 +30,25 @@ export class WhatsappService implements OnModuleInit {
|
||||
id SERIAL PRIMARY KEY,
|
||||
name VARCHAR(255) NOT NULL UNIQUE,
|
||||
content TEXT NOT NULL,
|
||||
area_id INTEGER REFERENCES areas (id) ON DELETE SET NULL,
|
||||
status VARCHAR(40) NOT NULL DEFAULT 'approved',
|
||||
requested_by_role VARCHAR(40),
|
||||
admin_approved_at TIMESTAMP WITH TIME ZONE,
|
||||
meta_submitted_at TIMESTAMP WITH TIME ZONE,
|
||||
meta_approved_at TIMESTAMP WITH TIME ZONE,
|
||||
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
|
||||
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
|
||||
);
|
||||
`);
|
||||
await this.db.query(`
|
||||
ALTER TABLE whatsapp_templates
|
||||
ADD COLUMN IF NOT EXISTS area_id INTEGER REFERENCES areas (id) ON DELETE SET NULL,
|
||||
ADD COLUMN IF NOT EXISTS status VARCHAR(40) NOT NULL DEFAULT 'approved',
|
||||
ADD COLUMN IF NOT EXISTS requested_by_role VARCHAR(40),
|
||||
ADD COLUMN IF NOT EXISTS admin_approved_at TIMESTAMP WITH TIME ZONE,
|
||||
ADD COLUMN IF NOT EXISTS meta_submitted_at TIMESTAMP WITH TIME ZONE,
|
||||
ADD COLUMN IF NOT EXISTS meta_approved_at TIMESTAMP WITH TIME ZONE;
|
||||
`);
|
||||
await this.db.query(`
|
||||
INSERT INTO whatsapp_templates (name, content) VALUES
|
||||
('aviso_fatura', 'Olá, {nome}. Estamos entrando em contato para lembrá-lo que a sua fatura está programada para {data}.'),
|
||||
@ -576,28 +591,128 @@ export class WhatsappService implements OnModuleInit {
|
||||
}
|
||||
|
||||
async getTemplates() {
|
||||
const res = await this.db.query('SELECT * FROM whatsapp_templates ORDER BY id ASC');
|
||||
await this.refreshFakeMetaApprovals();
|
||||
const res = await this.db.query(`
|
||||
SELECT
|
||||
wt.*,
|
||||
a.nome AS area_nome
|
||||
FROM whatsapp_templates wt
|
||||
LEFT JOIN areas a ON a.id = wt.area_id
|
||||
ORDER BY wt.id ASC
|
||||
`);
|
||||
return res.rows;
|
||||
}
|
||||
|
||||
private async getTemplateById(id: number) {
|
||||
await this.refreshFakeMetaApprovals();
|
||||
const res = await this.db.query('SELECT * FROM whatsapp_templates WHERE id = $1 LIMIT 1', [id]);
|
||||
return res.rows[0] || null;
|
||||
}
|
||||
|
||||
async saveTemplate(name: string, content: string) {
|
||||
async saveTemplate(name: string, content: string, areaId?: number | null, requestedByRole = 'admin') {
|
||||
const isSupervisor = requestedByRole === 'supervisor';
|
||||
const status = isSupervisor ? 'admin_review' : 'meta_review';
|
||||
const adminApprovedAt = isSupervisor ? null : 'CURRENT_TIMESTAMP';
|
||||
const metaSubmittedAt = isSupervisor ? null : 'CURRENT_TIMESTAMP';
|
||||
const res = await this.db.query(
|
||||
'INSERT INTO whatsapp_templates (name, content) VALUES ($1, $2) ON CONFLICT (name) DO UPDATE SET content = EXCLUDED.content, updated_at = CURRENT_TIMESTAMP RETURNING *',
|
||||
[name, content]
|
||||
`
|
||||
INSERT INTO whatsapp_templates (
|
||||
name,
|
||||
content,
|
||||
area_id,
|
||||
status,
|
||||
requested_by_role,
|
||||
admin_approved_at,
|
||||
meta_submitted_at,
|
||||
meta_approved_at,
|
||||
updated_at
|
||||
)
|
||||
VALUES ($1, $2, $3, $4, $5, ${adminApprovedAt}, ${metaSubmittedAt}, NULL, CURRENT_TIMESTAMP)
|
||||
ON CONFLICT (name) DO UPDATE SET
|
||||
content = EXCLUDED.content,
|
||||
area_id = EXCLUDED.area_id,
|
||||
status = EXCLUDED.status,
|
||||
requested_by_role = EXCLUDED.requested_by_role,
|
||||
admin_approved_at = EXCLUDED.admin_approved_at,
|
||||
meta_submitted_at = EXCLUDED.meta_submitted_at,
|
||||
meta_approved_at = NULL,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
RETURNING *
|
||||
`,
|
||||
[name, content, areaId || null, status, requestedByRole]
|
||||
);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
async updateTemplate(id: number, name: string, content: string) {
|
||||
async updateTemplate(id: number, name: string, content: string, areaId?: number | null) {
|
||||
const res = await this.db.query(
|
||||
'UPDATE whatsapp_templates SET name = $1, content = $2, updated_at = CURRENT_TIMESTAMP WHERE id = $3 RETURNING *',
|
||||
[name, content, id]
|
||||
`
|
||||
UPDATE whatsapp_templates
|
||||
SET
|
||||
name = $1,
|
||||
content = $2,
|
||||
area_id = $3,
|
||||
status = 'meta_review',
|
||||
admin_approved_at = CURRENT_TIMESTAMP,
|
||||
meta_submitted_at = CURRENT_TIMESTAMP,
|
||||
meta_approved_at = NULL,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $4
|
||||
RETURNING *
|
||||
`,
|
||||
[name, content, areaId || null, id]
|
||||
);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
async approveTemplateByAdmin(id: number) {
|
||||
const res = await this.db.query(
|
||||
`
|
||||
UPDATE whatsapp_templates
|
||||
SET
|
||||
status = 'meta_review',
|
||||
admin_approved_at = CURRENT_TIMESTAMP,
|
||||
meta_submitted_at = CURRENT_TIMESTAMP,
|
||||
meta_approved_at = NULL,
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $1
|
||||
RETURNING *
|
||||
`,
|
||||
[id],
|
||||
);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
async rejectTemplateByAdmin(id: number) {
|
||||
const res = await this.db.query(
|
||||
`
|
||||
UPDATE whatsapp_templates
|
||||
SET
|
||||
status = 'rejected',
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE id = $1
|
||||
RETURNING *
|
||||
`,
|
||||
[id],
|
||||
);
|
||||
return res.rows[0];
|
||||
}
|
||||
|
||||
async deleteTemplate(id: number) {
|
||||
await this.db.query('DELETE FROM whatsapp_templates WHERE id = $1', [id]);
|
||||
return { success: true };
|
||||
}
|
||||
|
||||
private async refreshFakeMetaApprovals() {
|
||||
await this.db.query(`
|
||||
UPDATE whatsapp_templates
|
||||
SET
|
||||
status = 'approved',
|
||||
meta_approved_at = COALESCE(meta_approved_at, meta_submitted_at + INTERVAL '15 minutes'),
|
||||
updated_at = CURRENT_TIMESTAMP
|
||||
WHERE status = 'meta_review'
|
||||
AND meta_submitted_at IS NOT NULL
|
||||
AND meta_submitted_at <= CURRENT_TIMESTAMP - INTERVAL '15 minutes'
|
||||
`);
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user