================================================================================
 RedFamosa — Changelog
 Self-hosted SMM panel with resellers, automatic order fulfilment and a wallet.
================================================================================


--------------------------------------------------------------------------------
 v1.0.2 — 13 August 2026
--------------------------------------------------------------------------------

This release is about one thing: every switch, field and dropdown in Settings
now does what its label says. We went through all of them one by one and fixed
each control that was not connected to anything. Nothing was removed from the
product, and no setting you have already saved changes meaning.

FIXED — settings that did not take effect

  · The Currency tab could not be saved at all. Choosing a thousands separator,
    a decimal separator, the number of decimals, the default markup, the
    rounding or the conversion rate and pressing Save appeared to work but
    stored nothing, so the tab always reopened on the previous values. All six
    fields now save, including a space as the thousands separator.

  · Settings → SEO did not reach the front page. A meta title and description
    entered there applied to the FAQ, Terms, blog and content pages but the
    home page ignored them and kept the title it shipped with. The home page
    now follows the same settings. If you have filled in the SEO fields inside
    the Landing editor those still win for the home page; leaving them empty
    now inherits the site-wide values instead of a fixed text.

  · The home page did not publish a canonical address, a share image or the
    indexing preference at all. It now does, from the same Settings → SEO
    values every other public page uses.

  · robots.txt ignored the "Allow search engines to index this site" switch.
    A file shipped with the script was being served instead of the live one, so
    the switch changed the page tags but never the file a crawler reads. That
    file is gone and robots.txt now follows the switch. An empty favicon.ico
    placeholder shipped beside it has been removed too, so a browser follows the
    icon your Branding settings declare instead of being handed a blank one.

  · The sitemap and the canonical tags disagreed with each other when a
    canonical host was configured: the sitemap kept listing the old address.
    Both now use the host you set.

  · "Rows per page" only reached about a third of the list screens. Tickets,
    transactions, staff, deposits, subscribers, subscriptions, domains,
    languages, news, webhooks, API keys, blacklists, activity logs, CRM
    contacts, the client's blog and the public service list all stayed on
    fifteen rows whatever you typed. They now all follow the setting. A few
    screens whose layout depends on their own page size keep it on purpose.

  · "Date format" changed almost nothing on screen, and "Timezone" changed
    nothing at all — dates were printed in a fixed format and in UTC. Both now
    apply everywhere a date is shown, including invoices and PDF exports, and
    month names follow the interface language. If a signed-in user has their
    own timezone set, theirs is used. Stored data is unchanged; this affects
    only what is displayed.

  · A reseller switching off "Disable signup" left their own storefront open.
    Registration on a reseller's domain was decided by the platform owner's
    switch instead of the reseller's, in four places including the page that
    actually creates the account. Each panel now decides for itself.

  · The sign-in page kept offering "Create one" after signups were switched
    off, and the home page still showed sign-up buttons, even though the
    registration page correctly turned visitors away. Those links are now
    hidden when signups are closed.

  · Analytics IDs were accepted and then silently discarded. A malformed GA4,
    Google Tag Manager or Meta pixel ID saved without complaint and reported
    success, but nothing was ever added to your pages. The form now checks the
    ID against the same rules the page uses and tells you what the correct
    shape looks like.

  · The "Enable API" switch did nothing — the public API, its documentation
    page and the client's API-key screen stayed open regardless. Switching it
    off now closes all three, and the API key entry disappears from the client
    menu.

  · "Auto convert currency" was never applied when importing a provider
    catalogue; the conversion box always opened unticked. It now follows the
    setting.

  · The password rules on the profile screens always read "at least 8
    characters" no matter what minimum you had set. They now show your number.

  · The support e-mail, phone and working hours had nowhere to appear on the
    default client skin, which does not include the footer that shows them.
    That skin now shows the same footer as the other two.

  · The minimum reCAPTCHA and platform-default fields were saved without any
    validation. They are now checked before being stored.

  · Reseller brand colours accepted any short text instead of a colour.

FIXED — appearance

  · A quotation mark in the landing page's font setting was written into the
    page in a form the browser could not read, which made the heading font fall
    back to a default. Colours, fonts and skin values are now written into the
    page correctly everywhere, and are checked before being used.

CHANGED

  · Removed the "Orders for average-time calc" field from Settings → Defaults.
    It was not used by any calculation in the product. No other setting is
    affected and nothing you have configured changes.

  · The "Enable API tab" switch is now labelled "Enable public API", because it
    controls the whole API rather than one screen.

--------------------------------------------------------------------------------
 v1.0.1 — 13 August 2026
--------------------------------------------------------------------------------

FIXED

  · Signing in with an expired session no longer dead-ends on "419 Page Expired".
    A sign-in page left open longer than the session lifetime — or one whose
    session the server discarded for any other reason — answered the submit with
    a blank error screen that offered nothing to click. The form now comes back
    with the e-mail still filled in and a line saying the session expired, and
    the next attempt signs in normally. The same applies to sign-up and to the
    password-reset request.

  · The session cookie name is now written to .env by the installer instead of
    being recomputed from the application name on every request. Renaming the
    panel in Settings no longer changes the cookie and signs everybody out, and
    a name written in a script that cannot be transliterated (Chinese, Japanese,
    an emoji-only name) no longer produces an unusable cookie name.

  · The installer no longer mangles a database password that contains a dollar
    sign followed by a digit — "S3cret$1pass" was written to .env as
    "S3cretpass", leaving the install unable to reach its own database with
    credentials the operator knew were correct.

  · An installation that cannot write its own .env now says exactly that, and
    which permission to change, on the first page. It used to fail with a
    generic server error.

  · The public landing page now uses the favicon uploaded in
    Settings → Branding. It previously kept a built-in icon whatever the
    operator uploaded.

  · The landing page's video player fills its frame instead of collapsing to a
    strip, and no longer ships pointing at a third-party sample clip: the
    "Watch demo" button appears once a video URL of your own is set.


--------------------------------------------------------------------------------
 v1.0.0 — 28 July 2026 — first public release
--------------------------------------------------------------------------------

WHAT IT IS

A white-label SMM panel you host yourself. You sell social-media services from
one or more upstream providers; your resellers get their own branded storefront
on their own domain, with their own customers, prices, wallet and support inbox,
inside your platform. A six-step web installer sets it up with no terminal.

Highlights:

  · Owner console, reseller console and customer portal, each with its own
    navigation, permissions and branding.
  · Money held in DECIMAL(18,6) and calculated with bcmath — never floats.
    Every balance change is a locked transaction with a signed, append-only
    ledger entry recording the balance after it.
  · Automatic order fulfilment against upstream providers, with status polling,
    drip-feed, refills, cancellations and a circuit breaker that stops calling a
    provider that has stopped answering.
  · Public key/action API, compatible with the SMM panel conventions bots
    already speak, with real idempotency on order placement.
  · Omnichannel CRM: WhatsApp, Messenger, Instagram, Telegram and e-mail in one
    inbox, with AI replies and a visual automation builder.
  · Custom domains per reseller, with real DNS verification.
  · English and Spanish throughout, light and dark, responsive to 375px.


SECURITY

  · Public API keys are stored as SHA-256 hashes. The columns that held them in
    cleartext are dropped. An existing key keeps working; nobody — including
    the platform owner, and including anyone holding a copy of the database —
    can read one back out. The customer's API screen shows a key once, at the
    moment it is created, and says so plainly.

  · Outbound webhooks are checked against a public-address guard before every
    delivery attempt, not once at save time, because DNS can be repointed
    between the two.

  · The base currency of a panel is validated against the currency catalogue and
    frozen once the panel's ledger has any history. Nothing in the product
    converts settled balances, so allowing the change would relabel them rather
    than convert them.

  · Third-party credentials (provider API keys, app secrets, OAuth client
    secrets) no longer use password-typed inputs, which browsers treat as
    credentials for this site — offering to save them and later autofilling the
    operator's own e-mail and password into a Client ID field.

  · The installer no longer writes the database password back into the page.


FIXED

  · Inbound CRM messages are de-duplicated by a database constraint instead of a
    check-then-insert. Two simultaneous deliveries of the same provider event
    could previously both be stored, which also fired the automation engine and
    the AI reply twice — answering a customer twice for one message.

  · The owner's Subscriptions screen filtered on a value nothing ever writes, so
    it was empty on every install. It now matches the same orders the customer's
    own subscriptions screen has always shown.

  · Every destructive action asks with the product's own dialog. It previously
    used the browser's built-in confirm popup, which cannot be themed, prints
    the server's hostname in its title bar, and offers to block further dialogs
    — on a white-label storefront, an unwanted announcement of the machine
    behind the brand.

  · Forms and actions refuse a second click while the first is still in flight.
    Two clicks on "Add funds" were two deposits; two on "Place order" were two
    orders that the upstream provider billed for twice.


ADDED

  · Admin → Security → Domains. Every hostname claimed across the platform, and
    the ability to release one. Hostnames are globally unique, so a reseller
    could claim a name, never verify it, and hold it for ever with no way to
    free it short of editing the database.

  · Admin → System → Webhooks. Register endpoints to receive a signed POST on
    every order status change, with retries and a delivery log.

  · Admin → Orders → Request refill. Support can now request a refill on a
    customer's behalf; previously only the customer could, from their own order
    list.


CHANGED

  · Two permissions were removed from the roles matrix: `platforms.manage` and
    `api.manage`. Neither guarded anything — there is no platform editor, and
    the only API control is the switch in Settings, already covered by
    `settings.manage`. A checkbox that decides nothing is worse than a missing
    one, because un-ticking it feels like closing a door.

  · New accounts are no longer given an API key at creation. Keys are stored
    hashed, so one minted before anybody could see it was unusable. The key is
    created on the first visit to the API screen and shown there once.


--------------------------------------------------------------------------------
 KNOWN LIMITATIONS IN v1.0.0
--------------------------------------------------------------------------------

Stated plainly, so nothing here is a surprise after purchase.

  · NO AFFILIATE PROGRAMME. The database carries a referral column and nothing
    reads it. There are no affiliate screens, no commission calculation and no
    payouts. Planned for a later release.

  · NO IN-HOUSE SUBSCRIPTION ENGINE. Subscription-type services work and are
    forwarded upstream with their posts / delay / expiry settings, but the
    RECURRENCE is executed by your provider, not by this panel. RedFamosa does
    not generate repeat orders on a schedule of its own.

  · NO PLATFORM EDITOR. Social networks (Instagram, TikTok, …) are created
    automatically when you import an upstream catalogue. You can organise
    services with Categories, but you cannot yet rename, reorder, re-icon or
    hide a network from the interface.

  · NO PUBLIC BLOG PAGES. Posts and categories can be written and managed in
    both the owner and reseller consoles; there is no public-facing blog route
    yet, so published posts are not reachable by visitors.

  · SSL FOR CUSTOM DOMAINS IS YOUR HOST'S JOB. Reseller domains are verified by
    DNS and routed by this product, but certificates are left to your hosting
    control panel (cPanel AutoSSL) or CDN (Cloudflare). The status is displayed;
    it is not issued here.

  · TIKTOK AND YOUTUBE ARE NOT CRM CHANNELS. WhatsApp, Messenger, Instagram,
    Telegram and e-mail are implemented. The other two are not.

  · TRANSACTIONAL E-MAIL IS MINIMAL. Subscription lifecycle notices are sent.
    Order, deposit and ticket events are shown in the interface but are not yet
    e-mailed. An editable template layer is planned.

  · ROLLING BACK THE API-KEY MIGRATION DOES NOT RESTORE KEYS. Hashing is
    one-way. If you roll that migration back, every user must generate a new
    key. This is a decision, not a routine step.


--------------------------------------------------------------------------------
 UPGRADING
--------------------------------------------------------------------------------

Run the migrations. Two of them change existing data:

  · API keys are hashed in place. Existing keys keep working and stop being
    readable. Nobody has to reconfigure a bot.

  · Duplicate CRM messages sharing an external id within a conversation are
    removed before a unique constraint is added, keeping the earliest of each
    group — the one whose automations and replies already ran.

Then run `php artisan app:seed-permissions`, which adds the new permissions and
deletes the two retired ones from existing installs.
