GBP Audit: show reviews scoring breakdown

Add details field to FieldStatus for passing breakdown info.
Display scoring breakdown like: "3 pkt (1. opinia) + 1 pkt (ocena) = 4/9"

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
Maciej Pienczyn 2026-01-09 04:30:04 +01:00
parent a25767e49c
commit 0c1d03418b
2 changed files with 49 additions and 5 deletions

View File

@ -68,6 +68,7 @@ class FieldStatus:
score: float = 0.0
max_score: float = 0.0
recommendation: Optional[str] = None
details: Optional[Dict[str, Any]] = None # Additional field-specific details
@dataclass
@ -622,17 +623,37 @@ class GBPAuditService:
status='complete',
value=f'{review_count} opinii, ocena {rating}',
score=max_score,
max_score=max_score
max_score=max_score,
details={
'review_count': review_count,
'rating': float(rating),
'base_score': 3,
'additional_score': min(review_count - 1, 4),
'rating_bonus': 1,
'breakdown': f'3 pkt (1. opinia) + {min(review_count - 1, 4)} pkt (kolejne) + 1 pkt (ocena) = {max_score}/{max_score}'
}
)
# PARTIAL: 1-4 reviews → proportional scoring
if review_count >= REVIEW_THRESHOLDS['minimum']:
# Base: 3 pts for first review + 1 pt per additional review (max 6 pts for 4 reviews)
partial_score = min(3 + (review_count - 1), max_score - 3) # max 6 pts
base_score = 3
additional_score = min(review_count - 1, 4)
partial_score = base_score + additional_score
# Bonus: +1 pt for good rating (>= 4.0)
rating_bonus = 0
if rating and float(rating) >= 4.0:
partial_score = min(partial_score + 1, max_score - 2) # max 7 pts
rating_bonus = 1
partial_score = min(partial_score + rating_bonus, max_score - 2) # max 7 pts
# Build breakdown string
breakdown_parts = [f'3 pkt (1. opinia)']
if additional_score > 0:
breakdown_parts.append(f'{additional_score} pkt (kolejne)')
if rating_bonus > 0:
breakdown_parts.append(f'1 pkt (ocena)')
breakdown = ' + '.join(breakdown_parts) + f' = {partial_score}/{max_score}'
return FieldStatus(
field_name='reviews',
@ -640,7 +661,15 @@ class GBPAuditService:
value=f'{review_count} opinii' + (f', ocena {rating}' if rating else ''),
score=partial_score,
max_score=max_score,
recommendation='Zachęcaj klientów do zostawiania opinii. Więcej pozytywnych recenzji zwiększa zaufanie.'
recommendation='Zachęcaj klientów do zostawiania opinii. Więcej pozytywnych recenzji zwiększa zaufanie.',
details={
'review_count': review_count,
'rating': float(rating) if rating else None,
'base_score': base_score,
'additional_score': additional_score,
'rating_bonus': rating_bonus,
'breakdown': breakdown
}
)
# MISSING: no reviews → 0/9 points
@ -650,7 +679,12 @@ class GBPAuditService:
value=review_count,
score=0,
max_score=max_score,
recommendation='Zbieraj opinie od klientów. Wizytówki z opiniami są bardziej wiarygodne i lepiej widoczne.'
recommendation='Zbieraj opinie od klientów. Wizytówki z opiniami są bardziej wiarygodne i lepiej widoczne.',
details={
'review_count': 0,
'rating': None,
'breakdown': '0 pkt (brak opinii)'
}
)
def _get_priority(self, field_status: FieldStatus) -> str:

View File

@ -293,6 +293,13 @@
color: var(--primary);
}
.scoring-breakdown-line {
margin-top: var(--spacing-xs);
font-size: var(--font-size-xs);
color: var(--text-tertiary);
font-family: monospace;
}
/* Recommendations Section */
.recommendations-section {
margin-bottom: var(--spacing-xl);
@ -913,6 +920,9 @@
{% else %}
<span class="scoring-message progress">👍 Dobry poczatek! Zbierz wiecej opinii - cel to minimum 5</span>
{% endif %}
{% if field_data.details and field_data.details.breakdown %}
<div class="scoring-breakdown-line">{{ field_data.details.breakdown }}</div>
{% endif %}
</div>
{% endif %}
<div class="field-score">