Readme
This commit is contained in:
99
README.md
Normal file
99
README.md
Normal file
@@ -0,0 +1,99 @@
|
|||||||
|
# ⚠️ INFORMAÇÕES CONFIDENCIAIS E PROPRIEDADE INTELECTUAL ⚠️
|
||||||
|
|
||||||
|
## 🚨 AVISO LEGAL IMPORTANTE
|
||||||
|
|
||||||
|
**ATENÇÃO: Este repositório contém informações CONFIDENCIAIS e PROPRIETÁRIAS.**
|
||||||
|
|
||||||
|
### ⛔ PROIBIÇÕES ABSOLUTAS
|
||||||
|
|
||||||
|
- **NÃO** compartilhe este código com terceiros
|
||||||
|
- **NÃO** faça fork, clone ou cópia sem autorização expressa
|
||||||
|
- **NÃO** utilize qualquer parte deste código em outros projetos
|
||||||
|
- **NÃO** distribua, venda ou comercialize este software
|
||||||
|
- **NÃO** reverse engineer ou descompile o código
|
||||||
|
- **NÃO** acesse sem permissão explícita do proprietário
|
||||||
|
|
||||||
|
### 🔒 DIREITOS DE PROPRIEDADE INTELECTUAL
|
||||||
|
|
||||||
|
Este software é propriedade exclusiva de **Daniel Arantes Loverde** e está protegido por:
|
||||||
|
|
||||||
|
- **Lei de Propriedade Intelectual (Lei 9.610/98)**
|
||||||
|
- **Lei de Software (Lei 9.609/98)**
|
||||||
|
- **Lei Geral de Proteção de Dados (LGPD - Lei 13.709/18)**
|
||||||
|
- **Direitos Autorais e Patentes**
|
||||||
|
|
||||||
|
### ⚖️ CONSEQUÊNCIAS LEGAIS
|
||||||
|
|
||||||
|
O acesso não autorizado, uso indevido, cópia ou distribuição deste código constitui:
|
||||||
|
|
||||||
|
- **CRIME** de violação de propriedade intelectual
|
||||||
|
- **CRIME** de roubo de propriedade intelectual
|
||||||
|
- **CRIME** de violação de direitos autorais
|
||||||
|
- **CRIME** de acesso não autorizado a sistema informatizado
|
||||||
|
|
||||||
|
**Penas previstas: 2 a 5 anos de reclusão + multa**
|
||||||
|
|
||||||
|
### 🛡️ MEDIDAS DE SEGURANÇA
|
||||||
|
|
||||||
|
- **Monitoramento**: Todo acesso é registrado e monitorado
|
||||||
|
- **Rastreamento**: IPs e atividades são rastreados
|
||||||
|
- **Logs**: Sistema completo de auditoria
|
||||||
|
- **Criptografia**: Dados protegidos com AES-256
|
||||||
|
- **Autenticação**: Acesso restrito com JWT + OTP
|
||||||
|
|
||||||
|
### 📧 CONTATO AUTORIZADO
|
||||||
|
|
||||||
|
**ÚNICO CONTATO VÁLIDO:**
|
||||||
|
- **Email**: daniel@loverde.com.br
|
||||||
|
- **Autorização**: Apenas via email oficial
|
||||||
|
|
||||||
|
### 🔐 CLASSIFICAÇÃO
|
||||||
|
|
||||||
|
**NÍVEL DE CONFIDENCIALIDADE: MÁXIMO**
|
||||||
|
- **Restrito**: Apenas para o proprietário
|
||||||
|
- **Não Divulgar**: Informações proprietárias
|
||||||
|
- **Não Compartilhar**: Código fonte protegido
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## ⚠️ DISCLAIMER FINAL
|
||||||
|
|
||||||
|
**Ao acessar este repositório, você concorda que:**
|
||||||
|
|
||||||
|
1. **Reconhece** que este é um software proprietário
|
||||||
|
2. **Compromete-se** a não violar os direitos de propriedade intelectual
|
||||||
|
3. **Aceita** as consequências legais por qualquer violação
|
||||||
|
4. **Entende** que o acesso é monitorado e rastreado
|
||||||
|
5. **Concorda** em respeitar todas as leis aplicáveis
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Sobre este repositório
|
||||||
|
|
||||||
|
App **PediFoods iOS** — projeto [Skip](https://skip.tools) dual-platform em
|
||||||
|
Swift/SwiftUI (`pedi-foods/`), transpilado para Android via skipstone. É o app
|
||||||
|
de produção e a **fonte da verdade** para requests, responses e comportamento;
|
||||||
|
o port nativo Android é construído em paridade com ele.
|
||||||
|
|
||||||
|
Build e execução: ver `pedi-foods/README.md` (Skip, `skip checkup`/`skip verify`,
|
||||||
|
Xcode + emulador Android). Testes via `swift test` / `skip test`.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Fluxo Git (desenvolvimento)
|
||||||
|
|
||||||
|
- Ao terminar cada task ou fatia lógica (ex.: fatia de checkout, ajuste de tela, correção de testes): fazer **commit imediato** com mensagem clara (`feat:`, `fix:`, `chore:`).
|
||||||
|
- Não commitar artefactos de build (`.build/`, saída do skipstone, `Darwin/` gerado) nem ficheiros de estado local irrelevantes para o projeto rodar a partir do código-fonte, salvo pedido explícito.
|
||||||
|
- O agente faz commit local; o push é sempre feito pelo Daniel após revisão.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**© 2024 Daniel Arantes Loverde. Todos os direitos reservados.**
|
||||||
|
|
||||||
|
**Última atualização: Junho 2026**
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
*Este documento é parte integrante do software e deve ser mantido confidencial.*
|
||||||
|
|
||||||
|
Autor: Daniel Arantes Loverde
|
||||||
@@ -487,6 +487,9 @@
|
|||||||
"Escolha o tamanho da sua fome" : {
|
"Escolha o tamanho da sua fome" : {
|
||||||
"comment" : "A label displayed below the pizza size selection.",
|
"comment" : "A label displayed below the pizza size selection.",
|
||||||
"isCommentAutoGenerated" : true
|
"isCommentAutoGenerated" : true
|
||||||
|
},
|
||||||
|
"Escolha seu sabor" : {
|
||||||
|
|
||||||
},
|
},
|
||||||
"Este sabor não possui adicionais." : {
|
"Este sabor não possui adicionais." : {
|
||||||
"comment" : "A message displayed when a pizza flavor does not have any add-ons.",
|
"comment" : "A message displayed when a pizza flavor does not have any add-ons.",
|
||||||
@@ -888,7 +891,16 @@
|
|||||||
},
|
},
|
||||||
"Pizza de varios sabores" : {
|
"Pizza de varios sabores" : {
|
||||||
"comment" : "A title displayed above the main content of the view.",
|
"comment" : "A title displayed above the main content of the view.",
|
||||||
"isCommentAutoGenerated" : true
|
"extractionState" : "stale",
|
||||||
|
"isCommentAutoGenerated" : true,
|
||||||
|
"localizations" : {
|
||||||
|
"en" : {
|
||||||
|
"stringUnit" : {
|
||||||
|
"state" : "translated",
|
||||||
|
"value" : "Escolha seu sabor"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"Política de Privacidade" : {
|
"Política de Privacidade" : {
|
||||||
"comment" : "The title of the privacy policy section.",
|
"comment" : "The title of the privacy policy section.",
|
||||||
|
|||||||
@@ -231,7 +231,7 @@ struct PizzaProductDetailSheet: View {
|
|||||||
)
|
)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: AppLayout.radiusXL, style: .continuous))
|
.clipShape(RoundedRectangle(cornerRadius: AppLayout.radiusXL, style: .continuous))
|
||||||
|
|
||||||
Text("Pizza de varios sabores")
|
Text("Escolha seu sabor")
|
||||||
.font(AppTypography.heading2)
|
.font(AppTypography.heading2)
|
||||||
.foregroundStyle(AppColors.textPrimary)
|
.foregroundStyle(AppColors.textPrimary)
|
||||||
|
|
||||||
@@ -291,7 +291,7 @@ struct PizzaProductDetailSheet: View {
|
|||||||
id: cartItemId,
|
id: cartItemId,
|
||||||
productId: selectedFlavorProducts.first?.id ?? category.id,
|
productId: selectedFlavorProducts.first?.id ?? category.id,
|
||||||
storeId: storeId,
|
storeId: storeId,
|
||||||
name: "Pizza de varios sabores",
|
name: "Escolha seu sabor",
|
||||||
imageURL: representativeImage,
|
imageURL: representativeImage,
|
||||||
details: selectedDetailsText,
|
details: selectedDetailsText,
|
||||||
choices: pizzaChoices.isEmpty ? nil : pizzaChoices,
|
choices: pizzaChoices.isEmpty ? nil : pizzaChoices,
|
||||||
|
|||||||
@@ -286,7 +286,7 @@ extension StoreDetailView {
|
|||||||
StoreCatalogListItem(
|
StoreCatalogListItem(
|
||||||
id: "\(category.id)::pizza-summary",
|
id: "\(category.id)::pizza-summary",
|
||||||
product: first,
|
product: first,
|
||||||
title: "Pizza de varios sabores",
|
title: "Escolha seu sabor",
|
||||||
description: "Escolha o tamanho da sua fome",
|
description: "Escolha o tamanho da sua fome",
|
||||||
imageURL: representativeImage ?? first.image,
|
imageURL: representativeImage ?? first.image,
|
||||||
isPizzaSummary: true,
|
isPizzaSummary: true,
|
||||||
|
|||||||
@@ -198,6 +198,7 @@ struct UserProfileView: View {
|
|||||||
let cleanEmail = email.trimmingCharacters(in: .whitespacesAndNewlines)
|
let cleanEmail = email.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
let normalizedPhone = normalizePhoneNumberForAPI(phone)
|
let normalizedPhone = normalizePhoneNumberForAPI(phone)
|
||||||
let cleanPhoto = profilePicture.trimmingCharacters(in: .whitespacesAndNewlines)
|
let cleanPhoto = profilePicture.trimmingCharacters(in: .whitespacesAndNewlines)
|
||||||
|
let newPhoto = cleanPhoto.hasPrefix("data:") ? cleanPhoto : nil
|
||||||
|
|
||||||
isSaving = true
|
isSaving = true
|
||||||
defer { isSaving = false }
|
defer { isSaving = false }
|
||||||
@@ -207,7 +208,7 @@ struct UserProfileView: View {
|
|||||||
name: cleanName,
|
name: cleanName,
|
||||||
email: cleanEmail,
|
email: cleanEmail,
|
||||||
phoneNumber: normalizedPhone,
|
phoneNumber: normalizedPhone,
|
||||||
profilePicture: cleanPhoto.isEmpty ? nil : cleanPhoto
|
profilePicture: newPhoto
|
||||||
)
|
)
|
||||||
|
|
||||||
if response.error {
|
if response.error {
|
||||||
@@ -231,10 +232,26 @@ struct UserProfileView: View {
|
|||||||
|
|
||||||
let cleanCpf = cpf.filter(\.isNumber)
|
let cleanCpf = cpf.filter(\.isNumber)
|
||||||
if cleanCpf.count == 11 {
|
if cleanCpf.count == 11 {
|
||||||
appState.profile.cpf = cleanCpf
|
guard isValidCPF(cleanCpf) else {
|
||||||
Task<Void, Never> {
|
SnackbarCenter.shared.show(
|
||||||
do { _ = try await ApiService().updateProfileCpf(cpf: cleanCpf) } catch {}
|
title: "CPF inválido. Verifique e tente novamente.",
|
||||||
|
style: .error,
|
||||||
|
icon: "xmark.octagon.fill",
|
||||||
|
duration: 3.0
|
||||||
|
)
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
let cpfResponse = try await ApiService().updateProfileCpf(cpf: cleanCpf)
|
||||||
|
if cpfResponse.error {
|
||||||
|
SnackbarCenter.shared.show(
|
||||||
|
title: cpfResponse.message ?? "Não foi possível atualizar o CPF.",
|
||||||
|
style: .error,
|
||||||
|
icon: "xmark.octagon.fill",
|
||||||
|
duration: 3.0
|
||||||
|
)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
appState.profile.cpf = cleanCpf
|
||||||
}
|
}
|
||||||
SessionStateStore.setActiveUserKey(
|
SessionStateStore.setActiveUserKey(
|
||||||
SessionStateStore.makeUserKey(profileId: appState.profile.id, email: appState.profile.email)
|
SessionStateStore.makeUserKey(profileId: appState.profile.id, email: appState.profile.email)
|
||||||
@@ -291,6 +308,20 @@ struct UserProfileView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private func isValidCPF(_ digits: String) -> Bool {
|
||||||
|
guard digits.count == 11, digits.unicodeScalars.allSatisfy({ CharacterSet.decimalDigits.contains($0) }) else { return false }
|
||||||
|
guard Set(digits).count > 1 else { return false }
|
||||||
|
func checkDigit(_ d: String, _ length: Int) -> Bool {
|
||||||
|
let sum = d.prefix(length).enumerated().reduce(0) { acc, pair in
|
||||||
|
acc + (Int(String(pair.element)) ?? 0) * (length + 1 - pair.offset)
|
||||||
|
}
|
||||||
|
let rem = (sum * 10) % 11
|
||||||
|
let expected = rem == 10 ? 0 : rem
|
||||||
|
return Int(String(d[d.index(d.startIndex, offsetBy: length)])) == expected
|
||||||
|
}
|
||||||
|
return checkDigit(digits, 9) && checkDigit(digits, 10)
|
||||||
|
}
|
||||||
|
|
||||||
#if os(iOS)
|
#if os(iOS)
|
||||||
@MainActor
|
@MainActor
|
||||||
private func applySelectedPhoto(_ item: PhotosPickerItem?) async {
|
private func applySelectedPhoto(_ item: PhotosPickerItem?) async {
|
||||||
|
|||||||
BIN
sim-home.png
BIN
sim-home.png
Binary file not shown.
|
Before Width: | Height: | Size: 134 KiB |
Reference in New Issue
Block a user