fix: login e termos de uso
This commit is contained in:
parent
c10caf9463
commit
5bcccce8a4
21
.claude/napkin.md
Normal file
21
.claude/napkin.md
Normal file
@ -0,0 +1,21 @@
|
||||
# Napkin Runbook
|
||||
|
||||
## Curation Rules
|
||||
- Re-prioritize on every read.
|
||||
- Keep recurring, high-value notes only.
|
||||
- Max 10 items per category.
|
||||
- Each item includes date + "Do instead".
|
||||
|
||||
## Execution & Validation (Highest Priority)
|
||||
_(empty — add entries as they emerge)_
|
||||
|
||||
## Shell & Command Reliability
|
||||
1. **[2026-03-30] Windows paths in bash tools need forward slash style**
|
||||
Do instead: use `C:/vscode/qrrapido` style, not `C:\...` or `/mnt/c/...` (WSL mount not available in this environment).
|
||||
|
||||
## Domain Behavior Guardrails
|
||||
_(empty — add entries as they emerge)_
|
||||
|
||||
## User Directives
|
||||
1. **[2026-03-30] Diagnose before fixing**
|
||||
Do instead: always present diagnosis and reasoning first; wait for user approval before touching code.
|
||||
@ -284,111 +284,30 @@ with open('qrcode.svg', 'wb') as f:
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<!-- ======================== PLANOS (teaser) ======================== -->
|
||||
<!-- ======================== PLANOS ======================== -->
|
||||
<section class="py-5 bg-light">
|
||||
<div class="container">
|
||||
<div class="text-center mb-5">
|
||||
<h2 class="fw-bold">@T("Planos para cada escala", "Planes para cada escala", "Plans for every scale")</h2>
|
||||
<p class="text-muted">@T("De projetos pessoais a sistemas de alto volume.", "De proyectos personales a sistemas de alto volumen.", "From personal projects to high-volume systems.")</p>
|
||||
</div>
|
||||
|
||||
<div class="row g-4 justify-content-center">
|
||||
<!-- Free -->
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100 border-0 shadow-sm text-center">
|
||||
<div class="card-header bg-secondary text-white py-3">
|
||||
<h5 class="mb-0">Free</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="display-6 fw-bold my-3">R$0</div>
|
||||
<ul class="list-unstyled text-start small">
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>10 req/min</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>500 req/@T("mês","mes","month")</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>PNG + WebP</li>
|
||||
<li class="mb-2 text-muted"><i class="fas fa-times me-2"></i>SVG</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Starter -->
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100 border-0 shadow-sm text-center">
|
||||
<div class="card-header bg-primary text-white py-3">
|
||||
<h5 class="mb-0">Starter</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="display-6 fw-bold my-3 text-muted">
|
||||
<i class="fas fa-lock fs-4 mb-1 d-block"></i>
|
||||
<span class="fs-6 fw-normal">@T("Faça login para ver o preço", "Iniciá sesión para ver el precio", "Log in to see pricing")</span>
|
||||
</div>
|
||||
<ul class="list-unstyled text-start small">
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>50 req/min</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>10.000 req/@T("mês","mes","month")</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>PNG + WebP + SVG</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>@T("Suporte e-mail","Soporte e-mail","Email support")</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Pro -->
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100 border-0 shadow border-warning text-center">
|
||||
<div class="card-header bg-warning text-dark py-3 position-relative">
|
||||
<h5 class="mb-0">Pro</h5>
|
||||
<span class="position-absolute top-0 end-0 translate-middle badge bg-danger" style="font-size:.6rem;">@T("Popular","Popular","Popular")</span>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="display-6 fw-bold my-3 text-muted">
|
||||
<i class="fas fa-lock fs-4 mb-1 d-block"></i>
|
||||
<span class="fs-6 fw-normal">@T("Faça login para ver o preço", "Iniciá sesión para ver el precio", "Log in to see pricing")</span>
|
||||
</div>
|
||||
<ul class="list-unstyled text-start small">
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>200 req/min</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>100.000 req/@T("mês","mes","month")</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>PNG + WebP + SVG</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>@T("Suporte prioritário","Soporte prioritario","Priority support")</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Business -->
|
||||
<div class="col-md-6 col-lg-3">
|
||||
<div class="card h-100 border-0 shadow-sm text-center">
|
||||
<div class="card-header bg-success text-white py-3">
|
||||
<h5 class="mb-0">Business</h5>
|
||||
</div>
|
||||
<div class="card-body">
|
||||
<div class="display-6 fw-bold my-3 text-muted">
|
||||
<i class="fas fa-lock fs-4 mb-1 d-block"></i>
|
||||
<span class="fs-6 fw-normal">@T("Faça login para ver o preço", "Iniciá sesión para ver el precio", "Log in to see pricing")</span>
|
||||
</div>
|
||||
<ul class="list-unstyled text-start small">
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>500 req/min</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>500.000 req/@T("mês","mes","month")</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>PNG + WebP + SVG</li>
|
||||
<li class="mb-2"><i class="fas fa-check text-success me-2"></i>@T("Suporte dedicado + SLA","Soporte dedicado + SLA","Dedicated support + SLA")</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Nota de login para preços -->
|
||||
<div class="alert alert-info text-center mt-4 mx-auto" style="max-width:560px;">
|
||||
<i class="fas fa-info-circle me-2"></i>
|
||||
<div class="text-center" style="max-width:640px; margin:0 auto;">
|
||||
<h2 class="fw-bold mb-3">@T("Planos para cada escala", "Planes para cada escala", "Plans for every scale")</h2>
|
||||
<p class="text-muted mb-4">
|
||||
@T(
|
||||
"Os preços dos planos pagos estão disponíveis após o login. O cadastro é gratuito e leva menos de 30 segundos.",
|
||||
"Los precios de los planes pagos están disponibles después del inicio de sesión. El registro es gratuito y lleva menos de 30 segundos.",
|
||||
"Paid plan pricing is available after logging in. Sign-up is free and takes under 30 seconds."
|
||||
"Temos planos para diferentes volumes de requisições, do uso pessoal ao alto volume empresarial. Todos os planos suportam PNG e WebP; os planos pagos liberam também o formato SVG.",
|
||||
"Tenemos planes para distintos volúmenes de solicitudes, desde uso personal hasta alto volumen empresarial. Todos los planes soportan PNG y WebP; los planes pagos habilitan también el formato SVG.",
|
||||
"We have plans for different request volumes, from personal use to high-volume enterprise. All plans support PNG and WebP; paid plans also unlock SVG output."
|
||||
)
|
||||
<div class="mt-2">
|
||||
<a href="/Account/Login" class="btn btn-primary btn-sm">
|
||||
<i class="fas fa-sign-in-alt me-1"></i>@T("Entrar / Criar conta", "Iniciar sesión / Crear cuenta", "Login / Create account")
|
||||
</p>
|
||||
@if (ViewBag.IsAuthenticated == true)
|
||||
{
|
||||
<a href="/Developer/Pricing" class="btn btn-primary">
|
||||
<i class="fas fa-tags me-2"></i>@T("Ver planos e preços", "Ver planes y precios", "View plans and pricing")
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
else
|
||||
{
|
||||
<a href="/Account/Login" class="btn btn-primary">
|
||||
<i class="fas fa-sign-in-alt me-2"></i>@T("Entrar para ver os planos", "Iniciá sesión para ver los planes", "Log in to view plans")
|
||||
</a>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
240
openapi.json
Normal file
240
openapi.json
Normal file
@ -0,0 +1,240 @@
|
||||
{
|
||||
"openapi": "3.0.1",
|
||||
"info": {
|
||||
"title": "QRRapido API",
|
||||
"description": "**QRRapido** — Ultra-fast QR Code generation API.\n\nGenerate QR codes for URLs, Pix payments, Wi-Fi, vCards, WhatsApp, SMS and more.\n\n**PT-BR:** Gere QR codes para URLs, Pix, Wi-Fi, vCard, WhatsApp, SMS e muito mais.\n\n**Authentication:** All endpoints (except `/ping`) require an API key sent in the `X-API-Key` header.\nGet your key at [qrrapido.site/Developer](https://qrrapido.site/Developer).",
|
||||
"contact": {
|
||||
"name": "QRRapido",
|
||||
"url": "https://qrrapido.site",
|
||||
"email": "contato@qrrapido.site"
|
||||
},
|
||||
"license": {
|
||||
"name": "Commercial — see qrrapido.site/terms"
|
||||
},
|
||||
"version": "v1"
|
||||
},
|
||||
"paths": {
|
||||
"/api/v1/QRManager/ping": {
|
||||
"get": {
|
||||
"tags": [
|
||||
"QRManager"
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"/api/v1/QRManager/generate": {
|
||||
"post": {
|
||||
"tags": [
|
||||
"QRManager"
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/QRGenerationRequest"
|
||||
}
|
||||
},
|
||||
"text/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/QRGenerationRequest"
|
||||
}
|
||||
},
|
||||
"application/*+json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/QRGenerationRequest"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"description": "OK",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/QRResponseDto"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"400": {
|
||||
"description": "Bad Request",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { }
|
||||
}
|
||||
}
|
||||
},
|
||||
"401": {
|
||||
"description": "Unauthorized",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { }
|
||||
}
|
||||
}
|
||||
},
|
||||
"402": {
|
||||
"description": "Payment Required",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { }
|
||||
}
|
||||
}
|
||||
},
|
||||
"429": {
|
||||
"description": "Too Many Requests",
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": { }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"components": {
|
||||
"schemas": {
|
||||
"QRGenerationRequest": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"type": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"content": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"quickStyle": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"primaryColor": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"backgroundColor": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"size": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"margin": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"cornerStyle": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"optimizeForSpeed": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"language": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"isPremium": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"hasLogo": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"logo": {
|
||||
"type": "string",
|
||||
"format": "byte",
|
||||
"nullable": true
|
||||
},
|
||||
"logoSizePercent": {
|
||||
"type": "integer",
|
||||
"format": "int32",
|
||||
"nullable": true
|
||||
},
|
||||
"applyLogoColorization": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"enableTracking": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"outputFormat": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
"QRResponseDto": {
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"success": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"qrCodeBase64": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"qrId": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"message": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"errorCode": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"remainingCredits": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"remainingFreeQRs": {
|
||||
"type": "integer",
|
||||
"format": "int32"
|
||||
},
|
||||
"fromCache": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"newDeviceId": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"generationTimeMs": {
|
||||
"type": "integer",
|
||||
"format": "int64"
|
||||
},
|
||||
"format": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
},
|
||||
"mimeType": {
|
||||
"type": "string",
|
||||
"nullable": true
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
}
|
||||
},
|
||||
"securitySchemes": {
|
||||
"ApiKey": {
|
||||
"type": "apiKey",
|
||||
"description": "Your QRRapido API key. Obtain one at https://qrrapido.site/Developer",
|
||||
"name": "X-API-Key",
|
||||
"in": "header"
|
||||
}
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"ApiKey": [ ]
|
||||
}
|
||||
]
|
||||
}
|
||||
Loading…
Reference in New Issue
Block a user