From f6ce624b291e248dc6e60917d59bfec53037a76a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Cau=C3=AA=20Faleiros?= Date: Thu, 1 Oct 2026 09:41:23 -0300 Subject: [PATCH] chore: a local demo customer for looking around Minha conta Co-Authored-By: Claude Opus 5.5 --- ops/demo_customer.py | 82 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 ops/demo_customer.py diff --git a/ops/demo_customer.py b/ops/demo_customer.py new file mode 100644 index 0000000..e5079ad --- /dev/null +++ b/ops/demo_customer.py @@ -0,0 +1,82 @@ +"""A demo customer for looking around Minha conta on the local stack. + + docker compose -f compose.local.yaml exec -T -e SITE_BASE_URL=http://site \ + -e SITE_HOST_HEADER=localhost api python -m ops.demo_customer + +Creates, once, an account with twelve paid orders in different stages, one in +correction and a cart waiting for PIX. Sign in at http://localhost:8080/conta +with DEMO_EMAIL and DEMO_PASSWORD below. Local test values only: the script +refuses to run anywhere but the local stack. +""" +import os +import sys +from uuid import uuid4 + +DEMO_EMAIL = 'demo@dropstar.test' +DEMO_PASSWORD = 'demo-dropstar-local' +DEMO_CNPJ = '11222333000181' + + +def main(): + if os.environ.get('APP_ENV') != 'local': + sys.exit('Only on the local stack.') + from app.core import db + import tests.smoke_test as smoke + from tests.smoke_test import Client, approved_quote, item_spec, upload_bytes + # Upload links are signed for the address the browser uses (localhost:9000), + # which inside this container is the container itself: send them to the + # storage service, keeping the signed Host. + public = os.environ.get('S3_PUBLIC_ENDPOINT', '').rstrip('/') + if public and public != 'http://storage:9000': + plain = smoke.urlopen + def via_storage(request, *args, **kwargs): + if isinstance(request, smoke.Request) and request.full_url.startswith(public + '/'): + request.add_header('Host', public.split('//', 1)[1]) + request.full_url = 'http://storage:9000' + request.full_url[len(public):] + return plain(request, *args, **kwargs) + smoke.urlopen = via_storage + with db.connect() as c: + if c.execute('SELECT 1 FROM dtf_local.accounts WHERE email=%s', (DEMO_EMAIL,)).fetchone(): + print(f'Demo customer already exists: {DEMO_EMAIL}') + return + client = Client() + client.call('/session') + profile = {'cnpj': DEMO_CNPJ, 'zap': '16999990000', 'mail': DEMO_EMAIL} + orders = [] + for i in range(12): + uid = upload_bytes(client, b'DEMO ARTWORK %d' % i) + item = item_spec('file', f'{1 + i * 0.3:.1f}', 0, uid) + quote = client.call('/quotes', {'request_key': str(uuid4()), 'customer': profile, 'items': [item], + 'freight': {'service': 'pickup'}}) + approved_quote(client, quote, [item]) + orders.append(client.call('/orders/dev-paid', {'quote_id': quote['id']})) + # Spread them over the production stages, one waiting for a correction. + stages = {0: ['tra', 'fil', 'imp', 'fin'], 1: ['tra', 'fil', 'imp', 'fin'], 2: ['tra', 'fil', 'imp'], + 3: ['tra', 'fil'], 4: ['tra'], 5: ['cor']} + for index, path in stages.items(): + order = orders[index] + version = order['version'] + for state in path: + if state == 'fil': + # The print queue takes approved final files, as on the Kanban. + final = upload_bytes(client, b'DEMO FINAL %d' % index, order_id=order['id']) + version = client.call('/operator/orders/' + order['id'] + '/final-files', + {'version': version, 'files': [{'item_index': 0, 'upload_id': final}], + 'note': 'Arquivo final da demonstração'}, operator=True)['version'] + body = {'state': state, 'version': version} + if state == 'cor': + body['reason'] = 'A arte está com fundo branco; envie em PNG com fundo transparente.' + version = client.call('/operator/orders/' + order['id'] + '/move', body, operator=True)['version'] + # The cart waiting for payment, with a PIX code open. + uid = upload_bytes(client, b'DEMO ARTWORK UNPAID') + item = item_spec('file', '2.3', 0, uid) + quote = client.call('/quotes', {'request_key': str(uuid4()), 'customer': profile, 'items': [item], + 'freight': {'service': 'pickup'}}) + approved_quote(client, quote, [item]) + client.call('/payments/intent', {'quote_id': quote['id'], 'method': {'type': 'pix'}}) + client.call('/account/register', {'customer': profile, 'password': DEMO_PASSWORD}) + print(f'Demo customer created: {DEMO_EMAIL}') + + +if __name__ == '__main__': + main()