mirror of
https://github.com/lucasrcsantana/story-generator.git
synced 2025-12-17 05:47:52 +00:00
Compare commits
No commits in common. "f883a6e9c2b18218990a91c9382f5f781632b68b" and "cdb98eb61d271a6b05a966b6d40071424210e03b" have entirely different histories.
f883a6e9c2
...
cdb98eb61d
34
CHANGELOG.md
34
CHANGELOG.md
@ -182,29 +182,25 @@ e este projeto adere ao [Semantic Versioning](https://semver.org/lang/pt-BR/).
|
|||||||
- Atualizado payload da Edge Function para incluir `language_type`
|
- Atualizado payload da Edge Function para incluir `language_type`
|
||||||
- Melhorada tipagem para suporte a múltiplos idiomas
|
- Melhorada tipagem para suporte a múltiplos idiomas
|
||||||
|
|
||||||
## [1.4.0] - 2024-03-28
|
## [1.4.0] - 2024-01-31
|
||||||
|
|
||||||
### Adicionado
|
### Adicionado
|
||||||
- Novas competências na análise de redações:
|
- Integração completa com a tabela `languages` do banco de dados
|
||||||
- Domínio da língua (0-200 pontos)
|
- Suporte para ícones de bandeira nos seletores de idioma
|
||||||
- Compreensão da proposta (0-200 pontos)
|
- Instruções específicas por idioma na interface
|
||||||
- Seleção de argumentos (0-200 pontos)
|
- Hook `useLanguages` para gerenciamento centralizado de idiomas
|
||||||
- Mecanismos linguísticos (0-200 pontos)
|
|
||||||
- Proposta de intervenção (0-200 pontos)
|
|
||||||
|
|
||||||
### Técnico
|
|
||||||
- Adicionados novos campos na tabela `essay_analyses` para armazenar as competências
|
|
||||||
- Atualizada a função `analyze-essay` para salvar as notas e justificativas das competências
|
|
||||||
- Adicionada restrição para garantir que os valores das competências estejam entre 0 e 200
|
|
||||||
|
|
||||||
### Modificado
|
### Modificado
|
||||||
- Melhorado o layout da página de análise de redações:
|
- Removido `LANGUAGE_OPTIONS` hard coded do `StoryGenerator`
|
||||||
- Separação clara entre critérios gerais e competências do ENEM
|
- Atualizado `CreateStoryPage` para usar `DEFAULT_LANGUAGE` do type
|
||||||
- Nova seção dedicada às competências do ENEM com layout aprimorado
|
- Melhorada a validação de idiomas usando dados do banco
|
||||||
- Barras de progresso mais visíveis para as competências
|
- Aprimorada a UX do seletor de idiomas com ícones e instruções
|
||||||
- Adicionadas descrições detalhadas para cada competência
|
|
||||||
- Cards coloridos para justificativas das competências
|
### Técnico
|
||||||
- Melhorias visuais nos critérios gerais de avaliação
|
- Refatorado o sistema de idiomas para usar dados dinâmicos do banco
|
||||||
|
- Adicionada tipagem forte para dados de idioma
|
||||||
|
- Implementada validação robusta de códigos de idioma
|
||||||
|
- Melhorada a estrutura de componentes para suportar dados dinâmicos
|
||||||
|
|
||||||
## [1.5.0] - 2024-03-19
|
## [1.5.0] - 2024-03-19
|
||||||
|
|
||||||
|
|||||||
@ -17,11 +17,7 @@ interface TimeFilterOption {
|
|||||||
months: number | null;
|
months: number | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface MetricNames {
|
const METRICS_CONFIG: MetricConfig[] = [
|
||||||
[key: string]: string;
|
|
||||||
}
|
|
||||||
|
|
||||||
const WRITING_METRICS: MetricConfig[] = [
|
|
||||||
{ key: 'score', name: 'Nota Geral', color: '#6366f1' },
|
{ key: 'score', name: 'Nota Geral', color: '#6366f1' },
|
||||||
{ key: 'adequacy', name: 'Adequação', color: '#f43f5e' },
|
{ key: 'adequacy', name: 'Adequação', color: '#f43f5e' },
|
||||||
{ key: 'coherence', name: 'Coerência', color: '#0ea5e9' },
|
{ key: 'coherence', name: 'Coerência', color: '#0ea5e9' },
|
||||||
@ -30,14 +26,6 @@ const WRITING_METRICS: MetricConfig[] = [
|
|||||||
{ key: 'grammar', name: 'Gramática', color: '#f59e0b' }
|
{ key: 'grammar', name: 'Gramática', color: '#f59e0b' }
|
||||||
];
|
];
|
||||||
|
|
||||||
const ENEM_METRICS: MetricConfig[] = [
|
|
||||||
{ key: 'language_domain', name: 'Domínio da Língua', color: '#f43f5e' },
|
|
||||||
{ key: 'proposal_comprehension', name: 'Compreensão da Proposta', color: '#0ea5e9' },
|
|
||||||
{ key: 'argument_selection', name: 'Seleção de Argumentos', color: '#10b981' },
|
|
||||||
{ key: 'linguistic_mechanisms', name: 'Mecanismos Linguísticos', color: '#8b5cf6' },
|
|
||||||
{ key: 'intervention_proposal', name: 'Proposta de Intervenção', color: '#f59e0b' }
|
|
||||||
];
|
|
||||||
|
|
||||||
const TIME_FILTERS: TimeFilterOption[] = [
|
const TIME_FILTERS: TimeFilterOption[] = [
|
||||||
{ value: '3m', label: '3 meses', months: 3 },
|
{ value: '3m', label: '3 meses', months: 3 },
|
||||||
{ value: '6m', label: '6 meses', months: 6 },
|
{ value: '6m', label: '6 meses', months: 6 },
|
||||||
@ -51,28 +39,13 @@ interface WritingMetricsChartProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function WritingMetricsChart({ data = [], className = '' }: WritingMetricsChartProps) {
|
export function WritingMetricsChart({ data = [], className = '' }: WritingMetricsChartProps) {
|
||||||
const [visibleWritingMetrics, setVisibleWritingMetrics] = React.useState<Set<string>>(
|
const [visibleMetrics, setVisibleMetrics] = React.useState<Set<string>>(
|
||||||
new Set(WRITING_METRICS.map(metric => metric.key))
|
new Set(METRICS_CONFIG.map(metric => metric.key))
|
||||||
);
|
|
||||||
const [visibleEnemMetrics, setVisibleEnemMetrics] = React.useState<Set<string>>(
|
|
||||||
new Set(ENEM_METRICS.map(metric => metric.key))
|
|
||||||
);
|
);
|
||||||
const [timeFilter, setTimeFilter] = React.useState<TimeFilter>('12m');
|
const [timeFilter, setTimeFilter] = React.useState<TimeFilter>('12m');
|
||||||
|
|
||||||
const toggleWritingMetric = (metricKey: string) => {
|
const toggleMetric = (metricKey: string) => {
|
||||||
setVisibleWritingMetrics(prev => {
|
setVisibleMetrics(prev => {
|
||||||
const newSet = new Set(prev);
|
|
||||||
if (newSet.has(metricKey)) {
|
|
||||||
newSet.delete(metricKey);
|
|
||||||
} else {
|
|
||||||
newSet.add(metricKey);
|
|
||||||
}
|
|
||||||
return newSet;
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleEnemMetric = (metricKey: string) => {
|
|
||||||
setVisibleEnemMetrics(prev => {
|
|
||||||
const newSet = new Set(prev);
|
const newSet = new Set(prev);
|
||||||
if (newSet.has(metricKey)) {
|
if (newSet.has(metricKey)) {
|
||||||
newSet.delete(metricKey);
|
newSet.delete(metricKey);
|
||||||
@ -103,13 +76,13 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
|||||||
|
|
||||||
const filteredData = React.useMemo(() => filterDataByTime(data), [data, timeFilter]);
|
const filteredData = React.useMemo(() => filterDataByTime(data), [data, timeFilter]);
|
||||||
|
|
||||||
const renderChart = (title: string, description: string, metrics: MetricConfig[], visibleMetrics: Set<string>, toggleMetric: (key: string) => void) => (
|
return (
|
||||||
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-8 mb-8">
|
<div className={`bg-white rounded-xl shadow-sm border border-gray-200 p-8 ${className}`}>
|
||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
<div className="flex items-center justify-between">
|
<div className="flex items-center justify-between">
|
||||||
<div className="space-y-1">
|
<div className="space-y-1">
|
||||||
<h2 className="text-xl font-semibold text-gray-900">{title}</h2>
|
<h2 className="text-xl font-semibold text-gray-900">Evolução da Escrita por Semana</h2>
|
||||||
<p className="text-sm text-gray-500">{description}</p>
|
<p className="text-sm text-gray-500">Acompanhe seu progresso na escrita ao longo do tempo</p>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-4">
|
<div className="flex items-center gap-4">
|
||||||
{/* Filtro de Período */}
|
{/* Filtro de Período */}
|
||||||
@ -133,7 +106,7 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className="text-gray-400 hover:text-gray-600 cursor-help transition-colors"
|
className="text-gray-400 hover:text-gray-600 cursor-help transition-colors"
|
||||||
title={`Gráfico mostrando a evolução das suas ${title.toLowerCase()} ao longo das semanas`}
|
title="Gráfico mostrando a evolução das suas métricas de escrita ao longo das semanas"
|
||||||
>
|
>
|
||||||
<HelpCircle className="h-4 w-4" />
|
<HelpCircle className="h-4 w-4" />
|
||||||
</div>
|
</div>
|
||||||
@ -142,7 +115,7 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
|||||||
|
|
||||||
{/* Pill Buttons */}
|
{/* Pill Buttons */}
|
||||||
<div className="flex flex-wrap gap-2 p-1">
|
<div className="flex flex-wrap gap-2 p-1">
|
||||||
{metrics.map(metric => (
|
{METRICS_CONFIG.map(metric => (
|
||||||
<button
|
<button
|
||||||
key={metric.key}
|
key={metric.key}
|
||||||
onClick={() => toggleMetric(metric.key)}
|
onClick={() => toggleMetric(metric.key)}
|
||||||
@ -206,9 +179,15 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
|||||||
/>
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
formatter={(value: number, name: string) => {
|
formatter={(value: number, name: string) => {
|
||||||
const metricNames: MetricNames = metrics.reduce((acc, m) => ({ ...acc, [m.key]: m.name }), {
|
const metricNames: { [key: string]: string } = {
|
||||||
|
score: 'Nota Geral',
|
||||||
|
adequacy: 'Adequação',
|
||||||
|
coherence: 'Coerência',
|
||||||
|
cohesion: 'Coesão',
|
||||||
|
vocabulary: 'Vocabulário',
|
||||||
|
grammar: 'Gramática',
|
||||||
minutesWriting: 'Minutos Escrevendo'
|
minutesWriting: 'Minutos Escrevendo'
|
||||||
});
|
};
|
||||||
return [value, metricNames[name] || name];
|
return [value, metricNames[name] || name];
|
||||||
}}
|
}}
|
||||||
contentStyle={{
|
contentStyle={{
|
||||||
@ -228,7 +207,7 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
|||||||
paddingBottom: '20px'
|
paddingBottom: '20px'
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
{metrics.map(metric => (
|
{METRICS_CONFIG.map(metric => (
|
||||||
visibleMetrics.has(metric.key) && (
|
visibleMetrics.has(metric.key) && (
|
||||||
<Line
|
<Line
|
||||||
key={metric.key}
|
key={metric.key}
|
||||||
@ -259,23 +238,4 @@ export function WritingMetricsChart({ data = [], className = '' }: WritingMetric
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
|
||||||
<div className={className}>
|
|
||||||
{renderChart(
|
|
||||||
"Evolução da Escrita por Semana",
|
|
||||||
"Acompanhe seu progresso na escrita ao longo do tempo",
|
|
||||||
WRITING_METRICS,
|
|
||||||
visibleWritingMetrics,
|
|
||||||
toggleWritingMetric
|
|
||||||
)}
|
|
||||||
{renderChart(
|
|
||||||
"Evolução das Competências do ENEM",
|
|
||||||
"Acompanhe seu progresso nas competências do ENEM ao longo do tempo",
|
|
||||||
ENEM_METRICS,
|
|
||||||
visibleEnemMetrics,
|
|
||||||
toggleEnemMetric
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
@ -67,16 +67,6 @@ interface EssayAnalysis {
|
|||||||
content_feedback: string;
|
content_feedback: string;
|
||||||
language_feedback: string;
|
language_feedback: string;
|
||||||
}>;
|
}>;
|
||||||
language_domain_value: number;
|
|
||||||
language_domain_justification: string;
|
|
||||||
proposal_comprehension_value: number;
|
|
||||||
proposal_comprehension_justification: string;
|
|
||||||
argument_selection_value: number;
|
|
||||||
argument_selection_justification: string;
|
|
||||||
linguistic_mechanisms_value: number;
|
|
||||||
linguistic_mechanisms_justification: string;
|
|
||||||
intervention_proposal_value: number;
|
|
||||||
intervention_proposal_justification: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface ProcessedEssayAnalysis {
|
interface ProcessedEssayAnalysis {
|
||||||
@ -96,28 +86,6 @@ interface ProcessedEssayAnalysis {
|
|||||||
content_feedback: string;
|
content_feedback: string;
|
||||||
language_feedback: string;
|
language_feedback: string;
|
||||||
};
|
};
|
||||||
competencies: {
|
|
||||||
language_domain: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
proposal_comprehension: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
argument_selection: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
linguistic_mechanisms: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
intervention_proposal: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function StudentDashboardPage() {
|
export function StudentDashboardPage() {
|
||||||
@ -202,11 +170,6 @@ export function StudentDashboardPage() {
|
|||||||
cohesion: 0,
|
cohesion: 0,
|
||||||
vocabulary: 0,
|
vocabulary: 0,
|
||||||
grammar: 0,
|
grammar: 0,
|
||||||
language_domain: 0,
|
|
||||||
proposal_comprehension: 0,
|
|
||||||
argument_selection: 0,
|
|
||||||
linguistic_mechanisms: 0,
|
|
||||||
intervention_proposal: 0,
|
|
||||||
minutesWriting: 0
|
minutesWriting: 0
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -218,11 +181,6 @@ export function StudentDashboardPage() {
|
|||||||
acc[week].cohesion += analysis.scores.cohesion;
|
acc[week].cohesion += analysis.scores.cohesion;
|
||||||
acc[week].vocabulary += analysis.scores.vocabulary;
|
acc[week].vocabulary += analysis.scores.vocabulary;
|
||||||
acc[week].grammar += analysis.scores.grammar;
|
acc[week].grammar += analysis.scores.grammar;
|
||||||
acc[week].language_domain += analysis.competencies.language_domain.value;
|
|
||||||
acc[week].proposal_comprehension += analysis.competencies.proposal_comprehension.value;
|
|
||||||
acc[week].argument_selection += analysis.competencies.argument_selection.value;
|
|
||||||
acc[week].linguistic_mechanisms += analysis.competencies.linguistic_mechanisms.value;
|
|
||||||
acc[week].intervention_proposal += analysis.competencies.intervention_proposal.value;
|
|
||||||
acc[week].minutesWriting += 30; // Tempo médio estimado por redação
|
acc[week].minutesWriting += 30; // Tempo médio estimado por redação
|
||||||
|
|
||||||
return acc;
|
return acc;
|
||||||
@ -237,11 +195,6 @@ export function StudentDashboardPage() {
|
|||||||
cohesion: Math.round(data.cohesion / data.count),
|
cohesion: Math.round(data.cohesion / data.count),
|
||||||
vocabulary: Math.round(data.vocabulary / data.count),
|
vocabulary: Math.round(data.vocabulary / data.count),
|
||||||
grammar: Math.round(data.grammar / data.count),
|
grammar: Math.round(data.grammar / data.count),
|
||||||
language_domain: Math.round(data.language_domain / data.count),
|
|
||||||
proposal_comprehension: Math.round(data.proposal_comprehension / data.count),
|
|
||||||
argument_selection: Math.round(data.argument_selection / data.count),
|
|
||||||
linguistic_mechanisms: Math.round(data.linguistic_mechanisms / data.count),
|
|
||||||
intervention_proposal: Math.round(data.intervention_proposal / data.count),
|
|
||||||
minutesWriting: data.minutesWriting
|
minutesWriting: data.minutesWriting
|
||||||
}))
|
}))
|
||||||
.sort((a, b) => a.week.localeCompare(b.week));
|
.sort((a, b) => a.week.localeCompare(b.week));
|
||||||
@ -389,17 +342,7 @@ export function StudentDashboardPage() {
|
|||||||
structure_feedback,
|
structure_feedback,
|
||||||
content_feedback,
|
content_feedback,
|
||||||
language_feedback
|
language_feedback
|
||||||
),
|
)
|
||||||
language_domain_value,
|
|
||||||
language_domain_justification,
|
|
||||||
proposal_comprehension_value,
|
|
||||||
proposal_comprehension_justification,
|
|
||||||
argument_selection_value,
|
|
||||||
argument_selection_justification,
|
|
||||||
linguistic_mechanisms_value,
|
|
||||||
linguistic_mechanisms_justification,
|
|
||||||
intervention_proposal_value,
|
|
||||||
intervention_proposal_justification
|
|
||||||
)
|
)
|
||||||
`)
|
`)
|
||||||
.eq('student_id', session.user.id)
|
.eq('student_id', session.user.id)
|
||||||
@ -430,28 +373,6 @@ export function StudentDashboardPage() {
|
|||||||
structure_feedback: analysis.essay_analysis_feedback?.[0]?.structure_feedback || '',
|
structure_feedback: analysis.essay_analysis_feedback?.[0]?.structure_feedback || '',
|
||||||
content_feedback: analysis.essay_analysis_feedback?.[0]?.content_feedback || '',
|
content_feedback: analysis.essay_analysis_feedback?.[0]?.content_feedback || '',
|
||||||
language_feedback: analysis.essay_analysis_feedback?.[0]?.language_feedback || ''
|
language_feedback: analysis.essay_analysis_feedback?.[0]?.language_feedback || ''
|
||||||
},
|
|
||||||
competencies: {
|
|
||||||
language_domain: {
|
|
||||||
value: analysis.language_domain_value || 0,
|
|
||||||
justification: analysis.language_domain_justification || ''
|
|
||||||
},
|
|
||||||
proposal_comprehension: {
|
|
||||||
value: analysis.proposal_comprehension_value || 0,
|
|
||||||
justification: analysis.proposal_comprehension_justification || ''
|
|
||||||
},
|
|
||||||
argument_selection: {
|
|
||||||
value: analysis.argument_selection_value || 0,
|
|
||||||
justification: analysis.argument_selection_justification || ''
|
|
||||||
},
|
|
||||||
linguistic_mechanisms: {
|
|
||||||
value: analysis.linguistic_mechanisms_value || 0,
|
|
||||||
justification: analysis.linguistic_mechanisms_justification || ''
|
|
||||||
},
|
|
||||||
intervention_proposal: {
|
|
||||||
value: analysis.intervention_proposal_value || 0,
|
|
||||||
justification: analysis.intervention_proposal_justification || ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
@ -468,24 +389,14 @@ export function StudentDashboardPage() {
|
|||||||
coherence: acc.coherence + (analysis.scores?.coherence || 0),
|
coherence: acc.coherence + (analysis.scores?.coherence || 0),
|
||||||
cohesion: acc.cohesion + (analysis.scores?.cohesion || 0),
|
cohesion: acc.cohesion + (analysis.scores?.cohesion || 0),
|
||||||
vocabulary: acc.vocabulary + (analysis.scores?.vocabulary || 0),
|
vocabulary: acc.vocabulary + (analysis.scores?.vocabulary || 0),
|
||||||
grammar: acc.grammar + (analysis.scores?.grammar || 0),
|
grammar: acc.grammar + (analysis.scores?.grammar || 0)
|
||||||
language_domain: acc.language_domain + (analysis.competencies?.language_domain?.value || 0),
|
|
||||||
proposal_comprehension: acc.proposal_comprehension + (analysis.competencies?.proposal_comprehension?.value || 0),
|
|
||||||
argument_selection: acc.argument_selection + (analysis.competencies?.argument_selection?.value || 0),
|
|
||||||
linguistic_mechanisms: acc.linguistic_mechanisms + (analysis.competencies?.linguistic_mechanisms?.value || 0),
|
|
||||||
intervention_proposal: acc.intervention_proposal + (analysis.competencies?.intervention_proposal?.value || 0)
|
|
||||||
}), {
|
}), {
|
||||||
score: 0,
|
score: 0,
|
||||||
adequacy: 0,
|
adequacy: 0,
|
||||||
coherence: 0,
|
coherence: 0,
|
||||||
cohesion: 0,
|
cohesion: 0,
|
||||||
vocabulary: 0,
|
vocabulary: 0,
|
||||||
grammar: 0,
|
grammar: 0
|
||||||
language_domain: 0,
|
|
||||||
proposal_comprehension: 0,
|
|
||||||
argument_selection: 0,
|
|
||||||
linguistic_mechanisms: 0,
|
|
||||||
intervention_proposal: 0
|
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Soma das métricas:', metricsSum);
|
console.log('Soma das métricas:', metricsSum);
|
||||||
@ -501,12 +412,7 @@ export function StudentDashboardPage() {
|
|||||||
averageCoherence: Math.round(metricsSum.coherence / totalAnalyses),
|
averageCoherence: Math.round(metricsSum.coherence / totalAnalyses),
|
||||||
averageCohesion: Math.round(metricsSum.cohesion / totalAnalyses),
|
averageCohesion: Math.round(metricsSum.cohesion / totalAnalyses),
|
||||||
averageVocabulary: Math.round(metricsSum.vocabulary / totalAnalyses),
|
averageVocabulary: Math.round(metricsSum.vocabulary / totalAnalyses),
|
||||||
averageGrammar: Math.round(metricsSum.grammar / totalAnalyses),
|
averageGrammar: Math.round(metricsSum.grammar / totalAnalyses)
|
||||||
averageLanguageDomain: Math.round(metricsSum.language_domain / totalAnalyses),
|
|
||||||
averageProposalComprehension: Math.round(metricsSum.proposal_comprehension / totalAnalyses),
|
|
||||||
averageArgumentSelection: Math.round(metricsSum.argument_selection / totalAnalyses),
|
|
||||||
averageLinguisticMechanisms: Math.round(metricsSum.linguistic_mechanisms / totalAnalyses),
|
|
||||||
averageInterventionProposal: Math.round(metricsSum.intervention_proposal / totalAnalyses)
|
|
||||||
};
|
};
|
||||||
|
|
||||||
console.log('Métricas de escrita calculadas:', writingMetrics);
|
console.log('Métricas de escrita calculadas:', writingMetrics);
|
||||||
@ -637,6 +543,72 @@ export function StudentDashboardPage() {
|
|||||||
{/* Gráfico de Evolução da Escrita */}
|
{/* Gráfico de Evolução da Escrita */}
|
||||||
<WritingMetricsChart data={weeklyMetrics.writing} className="mb-8" />
|
<WritingMetricsChart data={weeklyMetrics.writing} className="mb-8" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Histórias Recentes */}
|
||||||
|
<div>
|
||||||
|
<div className="flex justify-between items-center mb-6">
|
||||||
|
<h2 className="text-2xl font-bold text-gray-900">Histórias Recentes</h2>
|
||||||
|
<button
|
||||||
|
onClick={() => navigate('/aluno/historias')}
|
||||||
|
className="flex items-center gap-2 text-purple-600 hover:text-purple-700"
|
||||||
|
>
|
||||||
|
Ver todas
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{recentStories.length === 0 ? (
|
||||||
|
<div className="bg-white rounded-xl shadow-sm border border-gray-200 p-12 text-center">
|
||||||
|
<BookOpen className="h-12 w-12 text-gray-400 mx-auto mb-4" />
|
||||||
|
<h3 className="text-lg font-medium text-gray-900 mb-2">
|
||||||
|
Nenhuma história ainda
|
||||||
|
</h3>
|
||||||
|
<p className="text-gray-500 mb-6">
|
||||||
|
Comece sua jornada criando sua primeira história!
|
||||||
|
</p>
|
||||||
|
<button
|
||||||
|
onClick={() => navigate('/aluno/historias/nova')}
|
||||||
|
className="inline-flex items-center gap-2 px-4 py-2 bg-purple-600 text-white rounded-lg hover:bg-purple-700 transition"
|
||||||
|
>
|
||||||
|
<Plus className="h-5 w-5" />
|
||||||
|
Criar História
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6">
|
||||||
|
{recentStories.map((story) => (
|
||||||
|
<div
|
||||||
|
key={story.id}
|
||||||
|
className="bg-white rounded-xl shadow-sm border border-gray-200 overflow-hidden cursor-pointer hover:shadow-md transition"
|
||||||
|
onClick={() => navigate(`/aluno/historias/${story.id}`)}
|
||||||
|
>
|
||||||
|
{story.cover && (
|
||||||
|
<div className="relative aspect-video">
|
||||||
|
<img
|
||||||
|
src={`${story.cover.image_url}?width=400&height=300&quality=80&format=webp`}
|
||||||
|
alt={story.title}
|
||||||
|
className="w-full h-48 object-cover"
|
||||||
|
loading="lazy"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
<div className="p-6">
|
||||||
|
<h3 className="font-medium text-gray-900 mb-2">{story.title}</h3>
|
||||||
|
<div className="flex items-center justify-between text-sm text-gray-500">
|
||||||
|
<span>{new Date(story.created_at).toLocaleDateString()}</span>
|
||||||
|
<span className={`px-2 py-1 rounded-full text-xs font-medium ${
|
||||||
|
story.status === 'published'
|
||||||
|
? 'bg-green-100 text-green-800'
|
||||||
|
: 'bg-yellow-100 text-yellow-800'
|
||||||
|
}`}>
|
||||||
|
{story.status === 'published' ? 'Publicada' : 'Rascunho'}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -3,7 +3,7 @@ import { useParams, useNavigate } from 'react-router-dom';
|
|||||||
import { supabase } from '@/lib/supabase';
|
import { supabase } from '@/lib/supabase';
|
||||||
import { Button } from '@/components/ui/button';
|
import { Button } from '@/components/ui/button';
|
||||||
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card';
|
||||||
import { ArrowLeft, CheckCircle2, XCircle, BookOpen, Brain, MessageSquare, Puzzle, Target } from 'lucide-react';
|
import { ArrowLeft, CheckCircle2, XCircle } from 'lucide-react';
|
||||||
import { Progress } from '@/components/ui/progress';
|
import { Progress } from '@/components/ui/progress';
|
||||||
|
|
||||||
interface EssayAnalysis {
|
interface EssayAnalysis {
|
||||||
@ -25,28 +25,6 @@ interface EssayAnalysis {
|
|||||||
vocabulary: number;
|
vocabulary: number;
|
||||||
grammar: number;
|
grammar: number;
|
||||||
};
|
};
|
||||||
competencies: {
|
|
||||||
language_domain: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
proposal_comprehension: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
argument_selection: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
linguistic_mechanisms: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
intervention_proposal: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
created_at: string;
|
created_at: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -86,16 +64,6 @@ interface EssayAnalysisData {
|
|||||||
vocabulary: number;
|
vocabulary: number;
|
||||||
grammar: number;
|
grammar: number;
|
||||||
}>;
|
}>;
|
||||||
language_domain_value: number;
|
|
||||||
language_domain_justification: string;
|
|
||||||
proposal_comprehension_value: number;
|
|
||||||
proposal_comprehension_justification: string;
|
|
||||||
argument_selection_value: number;
|
|
||||||
argument_selection_justification: string;
|
|
||||||
linguistic_mechanisms_value: number;
|
|
||||||
linguistic_mechanisms_justification: string;
|
|
||||||
intervention_proposal_value: number;
|
|
||||||
intervention_proposal_justification: string;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function EssayAnalysis() {
|
export function EssayAnalysis() {
|
||||||
@ -149,17 +117,7 @@ export function EssayAnalysis() {
|
|||||||
cohesion,
|
cohesion,
|
||||||
vocabulary,
|
vocabulary,
|
||||||
grammar
|
grammar
|
||||||
),
|
)
|
||||||
language_domain_value,
|
|
||||||
language_domain_justification,
|
|
||||||
proposal_comprehension_value,
|
|
||||||
proposal_comprehension_justification,
|
|
||||||
argument_selection_value,
|
|
||||||
argument_selection_justification,
|
|
||||||
linguistic_mechanisms_value,
|
|
||||||
linguistic_mechanisms_justification,
|
|
||||||
intervention_proposal_value,
|
|
||||||
intervention_proposal_justification
|
|
||||||
`)
|
`)
|
||||||
.eq('essay_id', id)
|
.eq('essay_id', id)
|
||||||
.order('created_at', { ascending: false })
|
.order('created_at', { ascending: false })
|
||||||
@ -185,28 +143,6 @@ export function EssayAnalysis() {
|
|||||||
cohesion: analysisData.scores[0]?.cohesion || 0,
|
cohesion: analysisData.scores[0]?.cohesion || 0,
|
||||||
vocabulary: analysisData.scores[0]?.vocabulary || 0,
|
vocabulary: analysisData.scores[0]?.vocabulary || 0,
|
||||||
grammar: analysisData.scores[0]?.grammar || 0
|
grammar: analysisData.scores[0]?.grammar || 0
|
||||||
},
|
|
||||||
competencies: {
|
|
||||||
language_domain: {
|
|
||||||
value: analysisData.language_domain_value || 0,
|
|
||||||
justification: analysisData.language_domain_justification || ''
|
|
||||||
},
|
|
||||||
proposal_comprehension: {
|
|
||||||
value: analysisData.proposal_comprehension_value || 0,
|
|
||||||
justification: analysisData.proposal_comprehension_justification || ''
|
|
||||||
},
|
|
||||||
argument_selection: {
|
|
||||||
value: analysisData.argument_selection_value || 0,
|
|
||||||
justification: analysisData.argument_selection_justification || ''
|
|
||||||
},
|
|
||||||
linguistic_mechanisms: {
|
|
||||||
value: analysisData.linguistic_mechanisms_value || 0,
|
|
||||||
justification: analysisData.linguistic_mechanisms_justification || ''
|
|
||||||
},
|
|
||||||
intervention_proposal: {
|
|
||||||
value: analysisData.intervention_proposal_value || 0,
|
|
||||||
justification: analysisData.intervention_proposal_justification || ''
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -369,107 +305,6 @@ export function EssayAnalysis() {
|
|||||||
</Card>
|
</Card>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Nova seção de Competências do ENEM */}
|
|
||||||
<div className="mt-8 bg-white rounded-xl shadow-sm border border-gray-200 p-6">
|
|
||||||
<h2 className="text-2xl font-bold text-gray-900 mb-6">Competências do ENEM</h2>
|
|
||||||
<div className="grid grid-cols-1 gap-8">
|
|
||||||
{/* Competência 1 */}
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<BookOpen className="h-6 w-6 text-purple-600" />
|
|
||||||
<div>
|
|
||||||
<h3 className="text-lg font-semibold text-gray-900">Competência 1: Domínio da Língua</h3>
|
|
||||||
<p className="text-sm text-gray-500">Demonstrar domínio da modalidade escrita formal da Língua Portuguesa</p>
|
|
||||||
</div>
|
|
||||||
<div className="ml-auto">
|
|
||||||
<span className="text-2xl font-bold text-purple-600">{analysis.competencies.language_domain.value}</span>
|
|
||||||
<span className="text-gray-500">/200</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Progress value={(analysis.competencies.language_domain.value / 200) * 100} className="h-3" />
|
|
||||||
<p className="text-gray-600 bg-purple-50 rounded-lg p-4 border border-purple-100">
|
|
||||||
{analysis.competencies.language_domain.justification}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Competência 2 */}
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<Brain className="h-6 w-6 text-blue-600" />
|
|
||||||
<div>
|
|
||||||
<h3 className="text-lg font-semibold text-gray-900">Competência 2: Compreensão da Proposta</h3>
|
|
||||||
<p className="text-sm text-gray-500">Compreender a proposta de redação e aplicar conceitos das várias áreas de conhecimento</p>
|
|
||||||
</div>
|
|
||||||
<div className="ml-auto">
|
|
||||||
<span className="text-2xl font-bold text-blue-600">{analysis.competencies.proposal_comprehension.value}</span>
|
|
||||||
<span className="text-gray-500">/200</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Progress value={(analysis.competencies.proposal_comprehension.value / 200) * 100} className="h-3" />
|
|
||||||
<p className="text-gray-600 bg-blue-50 rounded-lg p-4 border border-blue-100">
|
|
||||||
{analysis.competencies.proposal_comprehension.justification}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Competência 3 */}
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<MessageSquare className="h-6 w-6 text-green-600" />
|
|
||||||
<div>
|
|
||||||
<h3 className="text-lg font-semibold text-gray-900">Competência 3: Seleção de Argumentos</h3>
|
|
||||||
<p className="text-sm text-gray-500">Selecionar, relacionar, organizar e interpretar informações, fatos, opiniões e argumentos</p>
|
|
||||||
</div>
|
|
||||||
<div className="ml-auto">
|
|
||||||
<span className="text-2xl font-bold text-green-600">{analysis.competencies.argument_selection.value}</span>
|
|
||||||
<span className="text-gray-500">/200</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Progress value={(analysis.competencies.argument_selection.value / 200) * 100} className="h-3" />
|
|
||||||
<p className="text-gray-600 bg-green-50 rounded-lg p-4 border border-green-100">
|
|
||||||
{analysis.competencies.argument_selection.justification}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Competência 4 */}
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<Puzzle className="h-6 w-6 text-orange-600" />
|
|
||||||
<div>
|
|
||||||
<h3 className="text-lg font-semibold text-gray-900">Competência 4: Mecanismos Linguísticos</h3>
|
|
||||||
<p className="text-sm text-gray-500">Demonstrar conhecimento dos mecanismos linguísticos necessários para a construção da argumentação</p>
|
|
||||||
</div>
|
|
||||||
<div className="ml-auto">
|
|
||||||
<span className="text-2xl font-bold text-orange-600">{analysis.competencies.linguistic_mechanisms.value}</span>
|
|
||||||
<span className="text-gray-500">/200</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Progress value={(analysis.competencies.linguistic_mechanisms.value / 200) * 100} className="h-3" />
|
|
||||||
<p className="text-gray-600 bg-orange-50 rounded-lg p-4 border border-orange-100">
|
|
||||||
{analysis.competencies.linguistic_mechanisms.justification}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Competência 5 */}
|
|
||||||
<div className="space-y-4">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<Target className="h-6 w-6 text-red-600" />
|
|
||||||
<div>
|
|
||||||
<h3 className="text-lg font-semibold text-gray-900">Competência 5: Proposta de Intervenção</h3>
|
|
||||||
<p className="text-sm text-gray-500">Elaborar proposta de intervenção para o problema abordado</p>
|
|
||||||
</div>
|
|
||||||
<div className="ml-auto">
|
|
||||||
<span className="text-2xl font-bold text-red-600">{analysis.competencies.intervention_proposal.value}</span>
|
|
||||||
<span className="text-gray-500">/200</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<Progress value={(analysis.competencies.intervention_proposal.value / 200) * 100} className="h-3" />
|
|
||||||
<p className="text-gray-600 bg-red-50 rounded-lg p-4 border border-red-100">
|
|
||||||
{analysis.competencies.intervention_proposal.justification}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -21,11 +21,6 @@ export interface WritingMetrics {
|
|||||||
averageCohesion: number;
|
averageCohesion: number;
|
||||||
averageVocabulary: number;
|
averageVocabulary: number;
|
||||||
averageGrammar: number;
|
averageGrammar: number;
|
||||||
averageLanguageDomain: number;
|
|
||||||
averageProposalComprehension: number;
|
|
||||||
averageArgumentSelection: number;
|
|
||||||
averageLinguisticMechanisms: number;
|
|
||||||
averageInterventionProposal: number;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface WeeklyReadingMetrics {
|
export interface WeeklyReadingMetrics {
|
||||||
@ -48,11 +43,6 @@ export interface WeeklyWritingMetrics {
|
|||||||
cohesion: number;
|
cohesion: number;
|
||||||
vocabulary: number;
|
vocabulary: number;
|
||||||
grammar: number;
|
grammar: number;
|
||||||
language_domain: number;
|
|
||||||
proposal_comprehension: number;
|
|
||||||
argument_selection: number;
|
|
||||||
linguistic_mechanisms: number;
|
|
||||||
intervention_proposal: number;
|
|
||||||
minutesWriting: number;
|
minutesWriting: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -27,28 +27,6 @@ interface EssayAnalysisResponse {
|
|||||||
vocabulary: number;
|
vocabulary: number;
|
||||||
grammar: number;
|
grammar: number;
|
||||||
};
|
};
|
||||||
competencies: {
|
|
||||||
language_domain: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
proposal_comprehension: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
argument_selection: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
linguistic_mechanisms: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
intervention_proposal: {
|
|
||||||
value: number;
|
|
||||||
justification: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interface EssayType {
|
interface EssayType {
|
||||||
@ -197,69 +175,6 @@ Forneça uma análise detalhada considerando:
|
|||||||
7. Pontos a melhorar
|
7. Pontos a melhorar
|
||||||
8. Sugestões específicas para aprimoramento
|
8. Sugestões específicas para aprimoramento
|
||||||
|
|
||||||
Essas são as competências do ENEM para você analisar a redação:
|
|
||||||
- Competência 1: Domínio da língua
|
|
||||||
- Competência 2: Compreensão da proposta
|
|
||||||
- Competência 3: Seleção de argumentos
|
|
||||||
- Competência 4: Mecanismos linguísticos
|
|
||||||
- Competência 5: Proposta de intervenção
|
|
||||||
|
|
||||||
## Competência 1: Demonstrar domínio da modalidade escrita formal da Língua Portuguesa
|
|
||||||
|
|
||||||
| Nota | Grade de Correção | Características |
|
|
||||||
|------|------------------|-----------------|
|
|
||||||
| 200 pontos | Demonstra excelente domínio da modalidade escrita formal da Língua Portuguesa e de escolha de registro. Desvios gramaticais ou de convenções da escrita serão aceitos somente como excepcionalidade e quando não caracterizem reincidência. | • Ausência de marcas de oralidade e de registro informal<br>• Precisão vocabular<br>• Obediência às regras gramaticais<br>• Não apresenta ou apresenta pouquíssimos desvios gramaticais leves e de convenções da escrita |
|
|
||||||
| 160 pontos | Demonstra bom domínio da modalidade escrita formal da Língua Portuguesa e de escolha de registro, com poucos desvios gramaticais e de convenções da escrita. | • Poucos desvios gramaticais leves<br>• Desvios de pontuação que não comprometem o sentido<br>• Desvios de ortografia e acentuação que não comprometem o sentido |
|
|
||||||
| 120 pontos | Demonstra domínio mediano da modalidade escrita formal da Língua Portuguesa e de escolha de registro, com alguns desvios gramaticais e de convenções da escrita. | • Alguns desvios gramaticais graves<br>• Problemas de concordância<br>• Problemas de regência<br>• Problemas de estrutura sintática<br>• Marcas de oralidade |
|
|
||||||
| 80 pontos | Demonstra domínio insuficiente da modalidade escrita formal da Língua Portuguesa, com muitos desvios gramaticais, de escolha de registro e de convenções da escrita. | • Grande quantidade de desvios graves<br>• Períodos incompletos<br>• Graves problemas de pontuação<br>• Desvios graves de grafia e acentuação<br>• Presença de gíria |
|
|
||||||
| 40 pontos | Demonstra domínio precário da modalidade escrita formal da Língua Portuguesa, de forma sistemática, com diversificados e frequentes desvios gramaticais. | • Graves e frequentes desvios gramaticais<br>• Presença de gírias e marcas de oralidade<br>• Desestruturação sintática em excesso |
|
|
||||||
| 0 ponto | Demonstra desconhecimento da modalidade escrita formal da Língua Portuguesa. | • Excesso de desvios que impossibilitam a compreensão |
|
|
||||||
|
|
||||||
## Competência 2: Compreender a proposta de redação e aplicar conceitos das várias áreas de conhecimento
|
|
||||||
|
|
||||||
| Nota | Grade de Correção | Características |
|
|
||||||
|------|------------------|-----------------|
|
|
||||||
| 200 pontos | Desenvolve o tema por meio de argumentação consistente, a partir de um repertório sociocultural produtivo, e apresenta excelente domínio do texto dissertativo-argumentativo. | • Tema muito bem desenvolvido<br>• Estrutura completa (introdução, argumentos, conclusão)<br>• Argumentos originais, além dos textos motivadores |
|
|
||||||
| 160 pontos | Desenvolve o tema por meio de argumentação consistente e apresenta bom domínio do texto dissertativo-argumentativo. | • Desenvolve bem o tema<br>• Boa argumentação<br>• Não se limita aos textos motivadores |
|
|
||||||
| 120 pontos | Desenvolve o tema por meio de argumentação previsível e apresenta domínio mediano do texto dissertativo-argumentativo. | • Abordagem superficial<br>• Argumentação previsível<br>• Reproduz ideias do senso comum |
|
|
||||||
| 80 pontos | Desenvolve o tema recorrendo à cópia de trechos dos textos motivadores ou apresenta domínio insuficiente do texto dissertativo-argumentativo. | • Tendência ao tangenciamento<br>• Argumentação falha<br>• Cópia dos textos motivadores |
|
|
||||||
| 40 pontos | Apresenta o assunto, tangenciando o tema, ou demonstra domínio precário do texto dissertativo-argumentativo. | • Tangencia o tema<br>• Ausência de argumentação<br>• Pode apresentar texto narrativo |
|
|
||||||
| 0 ponto | Fuga ao tema/não atendimento à estrutura dissertativo-argumentativa. | • Desenvolve outro tema<br>• Usa outra estrutura textual |
|
|
||||||
|
|
||||||
## Competência 3: Selecionar, relacionar, organizar e interpretar informações, fatos, opiniões e argumentos
|
|
||||||
|
|
||||||
| Nota | Grade de Correção | Características |
|
|
||||||
|------|------------------|-----------------|
|
|
||||||
| 200 pontos | Apresenta informações, fatos e opiniões relacionados ao tema proposto, de forma consistente e organizada, configurando autoria. | • Seleciona e organiza informações consistentemente<br>• Explicita tese clara<br>• Argumentos comprovam a tese |
|
|
||||||
| 160 pontos | Apresenta informações, fatos e opiniões relacionados ao tema, de forma organizada, com indícios de autoria. | • Organização consistente<br>• Argumentos previsíveis mas próprios |
|
|
||||||
| 120 pontos | Apresenta informações, fatos e opiniões relacionados ao tema, limitados aos argumentos dos textos motivadores. | • Organização pouco consistente<br>• Informações aleatórias<br>• Argumentos pouco convincentes |
|
|
||||||
| 80 pontos | Apresenta informações, fatos e opiniões relacionados ao tema, mas desorganizados ou contraditórios. | • Argumentos pouco articulados<br>• Reprodução dos textos motivadores |
|
|
||||||
| 40 pontos | Apresenta informações, fatos e opiniões pouco relacionados ao tema ou incoerentes. | • Sem defesa de ponto de vista<br>• Informações desarticuladas |
|
|
||||||
| 0 ponto | Apresenta informações, fatos e opiniões não relacionados ao tema. | • Informações incoerentes<br>• Sem ponto de vista |
|
|
||||||
|
|
||||||
## Competência 4: Demonstrar conhecimento dos mecanismos linguísticos necessários para a construção da argumentação
|
|
||||||
|
|
||||||
| Nota | Grade de Correção | Características |
|
|
||||||
|------|------------------|-----------------|
|
|
||||||
| 200 pontos | Articula bem as partes do texto e apresenta repertório diversificado de recursos coesivos. | • Articulação muito boa<br>• Pleno domínio dos recursos coesivos |
|
|
||||||
| 160 pontos | Articula as partes do texto com poucas inadequações e apresenta repertório diversificado de recursos coesivos. | • Boa articulação<br>• Poucos desvios nos conectores<br>• Algumas repetições desnecessárias |
|
|
||||||
| 120 pontos | Articula as partes do texto, de forma mediana, com inadequações. | • Algumas inadequações nos recursos coesivos<br>• Frases fragmentadas ocasionais<br>• Problemas de paragrafação |
|
|
||||||
| 80 pontos | Articula as partes do texto, de forma insuficiente, com muitas inadequações. | • Muitas inadequações<br>• Frases fragmentadas frequentes<br>• Problemas de estrutura |
|
|
||||||
| 40 pontos | Articula as partes do texto de forma precária. | • Graves problemas de articulação<br>• Períodos muito longos ou fragmentados<br>• Ausência de conectores |
|
|
||||||
| 0 ponto | Apresenta informações desconexas. | • Não se configura como texto |
|
|
||||||
|
|
||||||
## Competência 5: Elaborar proposta de intervenção para o problema abordado
|
|
||||||
|
|
||||||
| Nota | Grade de Correção | Características |
|
|
||||||
|------|------------------|-----------------|
|
|
||||||
| 200 pontos | Elabora muito bem proposta de intervenção, detalhada, relacionada ao tema. | • Proposta detalhada (o que fazer, como fazer, meios e participantes) |
|
|
||||||
| 160 pontos | Elabora bem proposta de intervenção relacionada ao tema. | • Proposta relacionada mas não totalmente detalhada |
|
|
||||||
| 120 pontos | Elabora, de forma mediana, proposta de intervenção relacionada ao tema. | • Proposta relacionada mas sem detalhamento |
|
|
||||||
| 80 pontos | Elabora, de forma insuficiente, proposta de intervenção. | • Proposta não atende totalmente à discussão |
|
|
||||||
| 40 pontos | Apresenta proposta de intervenção vaga, precária ou relacionada apenas ao assunto. | • Proposta vaga ou não configurada adequadamente |
|
|
||||||
| 0 ponto | Não apresenta proposta de intervenção ou apresenta proposta não relacionada ao tema. | • Ausência de proposta<br>• Proposta foge ao tema |
|
|
||||||
|
|
||||||
|
|
||||||
Responda em formato JSON seguindo exatamente esta estrutura:
|
Responda em formato JSON seguindo exatamente esta estrutura:
|
||||||
{
|
{
|
||||||
"overall_score": number, // 0 a 100
|
"overall_score": number, // 0 a 100
|
||||||
@ -277,28 +192,6 @@ Responda em formato JSON seguindo exatamente esta estrutura:
|
|||||||
"cohesion": number, // 0 a 100 - Coesão
|
"cohesion": number, // 0 a 100 - Coesão
|
||||||
"vocabulary": number, // 0 a 100 - Vocabulário
|
"vocabulary": number, // 0 a 100 - Vocabulário
|
||||||
"grammar": number // 0 a 100 - Gramática e ortografia
|
"grammar": number // 0 a 100 - Gramática e ortografia
|
||||||
},
|
|
||||||
"competencies": {
|
|
||||||
"language_domain": {
|
|
||||||
value: number, // 0 a 200 - Competência 1
|
|
||||||
justification: string // Justificativa para a pontuação
|
|
||||||
},
|
|
||||||
"proposal_comprehension": {
|
|
||||||
value: number, // 0 a 200 - Competência 2
|
|
||||||
justification: string // Justificativa para a pontuação
|
|
||||||
},
|
|
||||||
"argument_selection": {
|
|
||||||
value: number, // 0 a 200 - Competência 3
|
|
||||||
justification: string // Justificativa para a pontuação
|
|
||||||
},
|
|
||||||
"linguistic_mechanisms": {
|
|
||||||
value: number, // 0 a 200 - Competência 4
|
|
||||||
justification: string // Justificativa para a pontuação
|
|
||||||
},
|
|
||||||
"intervention_proposal": {
|
|
||||||
value: number, // 0 a 200 - Competência 5
|
|
||||||
justification: string // Justificativa para a pontuação
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}`
|
}`
|
||||||
|
|
||||||
@ -326,7 +219,7 @@ Responda em formato JSON seguindo exatamente esta estrutura:
|
|||||||
schema: {
|
schema: {
|
||||||
type: "object",
|
type: "object",
|
||||||
additionalProperties: false,
|
additionalProperties: false,
|
||||||
required: ["overall_score", "suggestions", "feedback", "strengths", "improvements", "criteria_scores", "competencies"],
|
required: ["overall_score", "suggestions", "feedback", "strengths", "improvements", "criteria_scores"],
|
||||||
properties: {
|
properties: {
|
||||||
overall_score: {
|
overall_score: {
|
||||||
type: "number",
|
type: "number",
|
||||||
@ -397,93 +290,6 @@ Responda em formato JSON seguindo exatamente esta estrutura:
|
|||||||
description: "Gramática e ortografia (0-100)"
|
description: "Gramática e ortografia (0-100)"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
|
||||||
competencies: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: false,
|
|
||||||
required: [
|
|
||||||
"language_domain",
|
|
||||||
"proposal_comprehension",
|
|
||||||
"argument_selection",
|
|
||||||
"linguistic_mechanisms",
|
|
||||||
"intervention_proposal"
|
|
||||||
],
|
|
||||||
properties: {
|
|
||||||
language_domain: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: false,
|
|
||||||
required: ["value", "justification"],
|
|
||||||
properties: {
|
|
||||||
value: {
|
|
||||||
type: "number",
|
|
||||||
description: "Pontuação da competência (0-200)"
|
|
||||||
},
|
|
||||||
justification: {
|
|
||||||
type: "string",
|
|
||||||
description: "Justificativa para a pontuação"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
proposal_comprehension: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: false,
|
|
||||||
required: ["value", "justification"],
|
|
||||||
properties: {
|
|
||||||
value: {
|
|
||||||
type: "number",
|
|
||||||
description: "Pontuação da competência (0-200)" },
|
|
||||||
justification: {
|
|
||||||
type: "string",
|
|
||||||
description: "Justificativa para a pontuação"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
argument_selection: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: false,
|
|
||||||
required: ["value", "justification"],
|
|
||||||
properties: {
|
|
||||||
value: {
|
|
||||||
type: "number",
|
|
||||||
description: "Pontuação da competência (0-200)"
|
|
||||||
},
|
|
||||||
justification: {
|
|
||||||
type: "string",
|
|
||||||
description: "Justificativa para a pontuação"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
linguistic_mechanisms: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: false,
|
|
||||||
required: ["value", "justification"],
|
|
||||||
properties: {
|
|
||||||
value: {
|
|
||||||
type: "number",
|
|
||||||
description: "Pontuação da competência (0-200)"
|
|
||||||
},
|
|
||||||
justification: {
|
|
||||||
type: "string",
|
|
||||||
description: "Justificativa para a pontuação"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
intervention_proposal: {
|
|
||||||
type: "object",
|
|
||||||
additionalProperties: false,
|
|
||||||
required: ["value", "justification"],
|
|
||||||
properties: {
|
|
||||||
value: {
|
|
||||||
type: "number",
|
|
||||||
description: "Pontuação da competência (0-200)"
|
|
||||||
},
|
|
||||||
justification: {
|
|
||||||
type: "string",
|
|
||||||
description: "Justificativa para a pontuação"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -504,18 +310,7 @@ Responda em formato JSON seguindo exatamente esta estrutura:
|
|||||||
.insert({
|
.insert({
|
||||||
essay_id,
|
essay_id,
|
||||||
overall_score: analysis.overall_score,
|
overall_score: analysis.overall_score,
|
||||||
suggestions: analysis.suggestions,
|
suggestions: analysis.suggestions
|
||||||
// Campos de competências
|
|
||||||
language_domain_value: analysis.competencies.language_domain.value,
|
|
||||||
language_domain_justification: analysis.competencies.language_domain.justification,
|
|
||||||
proposal_comprehension_value: analysis.competencies.proposal_comprehension.value,
|
|
||||||
proposal_comprehension_justification: analysis.competencies.proposal_comprehension.justification,
|
|
||||||
argument_selection_value: analysis.competencies.argument_selection.value,
|
|
||||||
argument_selection_justification: analysis.competencies.argument_selection.justification,
|
|
||||||
linguistic_mechanisms_value: analysis.competencies.linguistic_mechanisms.value,
|
|
||||||
linguistic_mechanisms_justification: analysis.competencies.linguistic_mechanisms.justification,
|
|
||||||
intervention_proposal_value: analysis.competencies.intervention_proposal.value,
|
|
||||||
intervention_proposal_justification: analysis.competencies.intervention_proposal.justification
|
|
||||||
})
|
})
|
||||||
.select()
|
.select()
|
||||||
.single()
|
.single()
|
||||||
|
|||||||
@ -1,52 +0,0 @@
|
|||||||
-- Adiciona campos de competências na tabela essay_analyses
|
|
||||||
ALTER TABLE essay_analyses
|
|
||||||
ADD COLUMN language_domain_value INTEGER,
|
|
||||||
ADD COLUMN language_domain_justification TEXT,
|
|
||||||
|
|
||||||
ADD COLUMN proposal_comprehension_value INTEGER,
|
|
||||||
ADD COLUMN proposal_comprehension_justification TEXT,
|
|
||||||
|
|
||||||
ADD COLUMN argument_selection_value INTEGER,
|
|
||||||
ADD COLUMN argument_selection_justification TEXT,
|
|
||||||
|
|
||||||
ADD COLUMN linguistic_mechanisms_value INTEGER,
|
|
||||||
ADD COLUMN linguistic_mechanisms_justification TEXT,
|
|
||||||
|
|
||||||
ADD COLUMN intervention_proposal_value INTEGER,
|
|
||||||
ADD COLUMN intervention_proposal_justification TEXT;
|
|
||||||
|
|
||||||
-- Adiciona restrições para garantir que os valores estejam entre 0 e 200
|
|
||||||
ALTER TABLE essay_analyses
|
|
||||||
ADD CONSTRAINT check_competency_values
|
|
||||||
CHECK (
|
|
||||||
language_domain_value BETWEEN 0 AND 200 AND
|
|
||||||
proposal_comprehension_value BETWEEN 0 AND 200 AND
|
|
||||||
argument_selection_value BETWEEN 0 AND 200 AND
|
|
||||||
linguistic_mechanisms_value BETWEEN 0 AND 200 AND
|
|
||||||
intervention_proposal_value BETWEEN 0 AND 200
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Atualiza as políticas de segurança para incluir os novos campos
|
|
||||||
ALTER POLICY "Estudantes podem ver suas próprias análises" ON essay_analyses
|
|
||||||
USING (
|
|
||||||
essay_id IN (
|
|
||||||
SELECT id FROM student_essays
|
|
||||||
WHERE student_id = auth.uid()
|
|
||||||
)
|
|
||||||
);
|
|
||||||
|
|
||||||
-- Comentários para documentação
|
|
||||||
COMMENT ON COLUMN essay_analyses.language_domain_value IS 'Valor da competência de domínio da língua (0-200)';
|
|
||||||
COMMENT ON COLUMN essay_analyses.language_domain_justification IS 'Justificativa para a nota de domínio da língua';
|
|
||||||
|
|
||||||
COMMENT ON COLUMN essay_analyses.proposal_comprehension_value IS 'Valor da competência de compreensão da proposta (0-200)';
|
|
||||||
COMMENT ON COLUMN essay_analyses.proposal_comprehension_justification IS 'Justificativa para a nota de compreensão da proposta';
|
|
||||||
|
|
||||||
COMMENT ON COLUMN essay_analyses.argument_selection_value IS 'Valor da competência de seleção de argumentos (0-200)';
|
|
||||||
COMMENT ON COLUMN essay_analyses.argument_selection_justification IS 'Justificativa para a nota de seleção de argumentos';
|
|
||||||
|
|
||||||
COMMENT ON COLUMN essay_analyses.linguistic_mechanisms_value IS 'Valor da competência de mecanismos linguísticos (0-200)';
|
|
||||||
COMMENT ON COLUMN essay_analyses.linguistic_mechanisms_justification IS 'Justificativa para a nota de mecanismos linguísticos';
|
|
||||||
|
|
||||||
COMMENT ON COLUMN essay_analyses.intervention_proposal_value IS 'Valor da competência de proposta de intervenção (0-200)';
|
|
||||||
COMMENT ON COLUMN essay_analyses.intervention_proposal_justification IS 'Justificativa para a nota de proposta de intervenção';
|
|
||||||
@ -1,20 +0,0 @@
|
|||||||
-- Remove a restrição de verificação dos valores
|
|
||||||
ALTER TABLE essay_analyses
|
|
||||||
DROP CONSTRAINT IF EXISTS check_competency_values;
|
|
||||||
|
|
||||||
-- Remove os campos de competências
|
|
||||||
ALTER TABLE essay_analyses
|
|
||||||
DROP COLUMN IF EXISTS language_domain_value,
|
|
||||||
DROP COLUMN IF EXISTS language_domain_justification,
|
|
||||||
|
|
||||||
DROP COLUMN IF EXISTS proposal_comprehension_value,
|
|
||||||
DROP COLUMN IF EXISTS proposal_comprehension_justification,
|
|
||||||
|
|
||||||
DROP COLUMN IF EXISTS argument_selection_value,
|
|
||||||
DROP COLUMN IF EXISTS argument_selection_justification,
|
|
||||||
|
|
||||||
DROP COLUMN IF EXISTS linguistic_mechanisms_value,
|
|
||||||
DROP COLUMN IF EXISTS linguistic_mechanisms_justification,
|
|
||||||
|
|
||||||
DROP COLUMN IF EXISTS intervention_proposal_value,
|
|
||||||
DROP COLUMN IF EXISTS intervention_proposal_justification;
|
|
||||||
Loading…
Reference in New Issue
Block a user