feat: undo mistaken moves, numbered pagination, and quieter Kanban messages
All checks were successful
Build and deploy / Validate source (push) Successful in 6s
Build and deploy / Integration suite on a real stack (push) Successful in 2m33s
Build and deploy / Secret scan and release gate (push) Successful in 7s
Build and deploy / Publish images (push) Successful in 1m48s
All checks were successful
Build and deploy / Validate source (push) Successful in 6s
Build and deploy / Integration suite on a real stack (push) Successful in 2m33s
Build and deploy / Secret scan and release gate (push) Successful in 7s
Build and deploy / Publish images (push) Successful in 1m48s
Moves: an order can go back one stage (BACK in app/runtime.py) with an internal reason, flagged in the history as movements.back. The customer is not notified and approved finals stay; "production started" and "ready" are now enqueued once per order, so undoing and redoing a move sends nothing twice. Dragging only goes forward and highlights the allowed column. Move errors are in Portuguese. Lists: the send log, payments (open, resolved as history, all) and quotes are paged on the server with a total, 20 rows by default (10/20/50/100), first/previous/page/next/last. The send log filters by destination, status, event and order. Older finished orders load on demand. The board no longer carries the send log or payment rows, only the open-payment count. Kanban: Pagamentos and Integrações are separate tabs; messages are brief, bottom notifications that clear themselves; wording is shorter. Full CI integration sequence passes locally, with new checks for undo, paging and filters. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -141,17 +141,43 @@ def run():
|
||||
outcome = deliver({'event_id': event_id, 'reference': quote_id,
|
||||
'status': 'approved', 'amount_cents': total - 1})
|
||||
assert outcome['outcome'].startswith('refused'), outcome
|
||||
issues = client.call('/operator/board', operator=True)['payment_issues']
|
||||
issues = client.call('/operator/payment-events?state=open&limit=100', operator=True)['issues']
|
||||
issue = next(i for i in issues if i['event_id'] == event_id)
|
||||
assert client.call('/operator/board', operator=True)['payment_issues_total'] >= 1
|
||||
client.call('/operator/payment-events/' + issue['id'] + '/resolve', {'note': 'no'},
|
||||
operator=True, expected=422)
|
||||
client.call('/operator/payment-events/' + issue['id'] + '/resolve',
|
||||
{'note': 'Local test: refunded the underpayment'}, operator=True)
|
||||
client.call('/operator/payment-events/' + issue['id'] + '/resolve',
|
||||
{'note': 'Local test: second resolution'}, operator=True, expected=404)
|
||||
issues = client.call('/operator/board', operator=True)['payment_issues']
|
||||
issues = client.call('/operator/payment-events?state=open&limit=100', operator=True)['issues']
|
||||
assert not any(i['event_id'] == event_id for i in issues)
|
||||
print('PASS: refused paid notification is listed until an operator resolves it')
|
||||
resolved_page = client.call('/operator/payment-events?state=resolved&limit=100', operator=True)
|
||||
assert resolved_page['total'] >= 1
|
||||
resolved = resolved_page['issues']
|
||||
done = next(i for i in resolved if i['event_id'] == event_id)
|
||||
assert done['resolution'] == 'Local test: refunded the underpayment' and done['resolved_by']
|
||||
print('PASS: refused paid notification is listed until an operator resolves it, then kept as history')
|
||||
|
||||
# The send log pages by id and filters by destination, status, event and order.
|
||||
page = client.call('/operator/events?limit=2', operator=True)
|
||||
assert len(page['events']) == 2 and page['total'] > 2
|
||||
second = client.call('/operator/events?limit=2&offset=2', operator=True)
|
||||
assert all(e['id'] < page['events'][-1]['id'] for e in second['events'])
|
||||
assert second['total'] == page['total']
|
||||
tiny = client.call('/operator/events?provider=tiny&event=payment_approved&status=delivered&limit=100', operator=True)
|
||||
assert tiny['events'] and all(e['provider'] == 'tiny' and e['payload']['event'] == 'payment_approved'
|
||||
and e['delivered_at'] for e in tiny['events'])
|
||||
client.call('/operator/events?provider=email', operator=True, expected=422)
|
||||
client.call('/operator/events?limit=500', operator=True, expected=422)
|
||||
quotes = client.call('/operator/quotes?kind=approved&limit=1&offset=0', operator=True)
|
||||
assert 'total' in quotes and len(quotes['quotes']) <= 1
|
||||
finished = client.call('/operator/orders/finished?limit=1', operator=True)
|
||||
if finished['orders']:
|
||||
last = finished['orders'][-1]
|
||||
client.call('/operator/orders/finished?before_created_at=' + last['created_at'].replace('+', '%2B')
|
||||
+ '&before_id=' + last['id'], operator=True)
|
||||
print('PASS: send log, payment history and finished orders page and filter')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
Reference in New Issue
Block a user